aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/LuaJIT-1.1.7/jit
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/LuaJIT-1.1.7/jit')
-rw-r--r--libraries/LuaJIT-1.1.7/jit/dis_x86.lua622
-rw-r--r--libraries/LuaJIT-1.1.7/jit/dump.lua265
-rw-r--r--libraries/LuaJIT-1.1.7/jit/dumphints.lua239
-rw-r--r--libraries/LuaJIT-1.1.7/jit/opt.lua508
-rw-r--r--libraries/LuaJIT-1.1.7/jit/opt_inline.lua397
-rw-r--r--libraries/LuaJIT-1.1.7/jit/trace.lua111
6 files changed, 0 insertions, 2142 deletions
diff --git a/libraries/LuaJIT-1.1.7/jit/dis_x86.lua b/libraries/LuaJIT-1.1.7/jit/dis_x86.lua
deleted file mode 100644
index b9ca150..0000000
--- a/libraries/LuaJIT-1.1.7/jit/dis_x86.lua
+++ /dev/null
@@ -1,622 +0,0 @@
1----------------------------------------------------------------------------
2-- LuaJIT x86 disassembler module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- This is a helper module used by the LuaJIT machine code dumper module.
8--
9-- Sending small code snippets to an external disassembler and mixing the
10-- output with our own stuff was too fragile. So I had to bite the bullet
11-- and write yet another x86 disassembler. Oh well ...
12--
13-- The output format is very similar to what ndisasm generates. But it has
14-- been developed independently by looking at the opcode tables from the
15-- Intel and AMD manuals. The supported instruction set is quite extensive
16-- and reflects what a current generation P4 or K8 implements in 32 bit
17-- mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3 and even privileged
18-- instructions.
19--
20-- Notes:
21-- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported.
22-- * No attempt at optimization has been made -- it's fast enough for my needs.
23-- * The public API may change when more architectures are added.
24--
25-- TODO:
26-- * More testing with arbitrary x86 code (not just LuaJIT generated code).
27-- * The output for a few MMX/SSE opcodes could be improved.
28-- * Adding x64 support would be straightforward.
29-- * Better input API (iterator) and output API (structured access to instr).
30------------------------------------------------------------------------------
31
32local type = type
33local sub, byte, format = string.sub, string.byte, string.format
34local match, gmatch, gsub = string.match, string.gmatch, string.gsub
35
36-- Map for 1st opcode byte. Ugly? Well ... read on.
37local map_opc1 = {
38--0x
39[0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es",
40"orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*",
41--1x
42"adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss",
43"sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds",
44--2x
45"andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa",
46"subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das",
47--3x
48"xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa",
49"cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas",
50--4x
51"incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR",
52"decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR",
53--5x
54"pushVR","pushVR","pushVR","pushVR","pushVR","pushVR","pushVR","pushVR",
55"popVR","popVR","popVR","popVR","popVR","popVR","popVR","popVR",
56--6x
57"pusha/pushaw","popa/popaw","boundVrm","arplWmr",
58"fs:seg","gs:seg","o16:","a16",
59"pushVi","imulVrmi","pushBs","imulVrms",
60"insb","insd/insw","outsb","outsd/outsw",
61--7x
62"joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj",
63"jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj",
64--8x
65"arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms",
66"testBmr","testVmr","xchgBrm","xchgVrm",
67"movBmr","movVmr","movBrm","movVrm",
68"movVmg","leaVrm","movWgm","popVm",
69--9x
70"nop|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR",
71"xchgVaR","xchgVaR","xchgVaR","xchgVaR",
72"cwde/cbw","cdq/cwd","call farViw","wait",
73"pushf/pushfw","popf/popfw","sahf","lahf",
74--Ax
75"movBao","movVao","movBoa","movVoa",
76"movsb","movsd/movsb","cmpsb","cmpsd/cmpsw",
77"testBai","testVai","stosb","stosd/stosw",
78"lodsb","lodsd/lodsw","scasb","scasd/scasw",
79--Bx
80"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
81"movVRi","movVRi","movVRi","movVRi","movVRi","movVRi","movVRi","movVRi",
82--Cx
83"shift!Bmu","shift!Vmu","retBw","ret","lesVrm","ldsVrm","movBmi","movVmi",
84"enterBwu","leave","retfBw","retf","int3","intBu","into","iret/iretw",
85--Dx
86"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
87"fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7",
88--Ex
89"loopneBj","loopeBj","loopBj","jecxz/jcxzBj","inBau","inVau","outBua","outVua",
90"callDj","jmpDj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda",
91--Fx
92"lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm",
93"clc","stc","cli","sti","cld","std","inc!Bm","inc!Vm",
94}
95assert(#map_opc1 == 255)
96
97-- Map for 2nd opcode byte (0f xx). True CISC hell. Hey, I told you.
98-- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne
99local map_opc2 = {
100--0x
101[0]="sldt!Dmp","sgdt!Dmp","larVrm","lslVrm",nil,"syscall","clts","sysret",
102"invd","wbinvd",nil,"ud1",nil,"prefetch!Bm","femms","3dnowMrmu",
103--1x
104"movupsXrm|movssXrm|movupdXrm|movsdXrm",
105"movupsXmr|movssXmr|movupdXmr|movsdXmr",
106"movhlpsXrm|movsldupXrm|movlpdXrm|movddupXrm", -- TODO: movlpsXrMm (mem case).
107"movlpsXmr||movlpdXmr",
108"unpcklpsXrm||unpcklpdXrm",
109"unpckhpsXrm||unpckhpdXrm",
110"movlhpsXrm|movshdupXrm|movhpdXrm", -- TODO: movhpsXrMm (mem case).
111"movhpsXmr||movhpdXmr",
112"prefetcht!Bm","hintnopBm","hintnopBm","hintnopBm",
113"hintnopBm","hintnopBm","hintnopBm","hintnopBm",
114--2x
115"movDmx","movDmy","movDxm","movDym","movDmz",nil,"movDzm",nil,
116"movapsXrm||movapdXrm",
117"movapsXmr||movapdXmr",
118"cvtpi2psXrMm|cvtsi2ssXrDm|cvtpi2pdXrMm|cvtsi2sdXrDm",
119"movntpsXmr||movntpdXmr",
120"cvttps2piMrXm|cvttss2siDrXm|cvttpd2piMrXm|cvttsd2siDrXm",
121"cvtps2piMrXm|cvtss2siDrXm|cvtpd2piMrXm|cvtsd2siDrXm",
122"ucomissXrm||ucomisdXrm",
123"comissXrm||comisdXrm",
124--3x
125"wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,nil,
126"ssse3*38",nil,"ssse3*3a",nil,nil,nil,nil,nil,
127--4x
128"cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm",
129"cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm",
130"cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm",
131"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
132--5x
133"movmskpsDrXm||movmskpdDrXm","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
134"rsqrtpsXrm|rsqrtssXrm","rcppsXrm|rcpssXrm",
135"andpsXrm||andpdXrm","andnpsXrm||andnpdXrm",
136"orpsXrm||orpdXrm","xorpsXrm||xorpdXrm",
137"addpsXrm|addssXrm|addpdXrm|addsdXrm","mulpsXrm|mulssXrm|mulpdXrm|mulsdXrm",
138"cvtps2pdXrm|cvtss2sdXrm|cvtpd2psXrm|cvtsd2ssXrm",
139"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
140"subpsXrm|subssXrm|subpdXrm|subsdXrm","minpsXrm|minssXrm|minpdXrm|minsdXrm",
141"divpsXrm|divssXrm|divpdXrm|divsdXrm","maxpsXrm|maxssXrm|maxpdXrm|maxsdXrm",
142--6x
143"punpcklbwMrm||punpcklbqXrm","punpcklwdPrm","punpckldqPrm","packsswbPrm",
144"pcmpgtbPrm","pcmpgtwPrm","pcmpgtdPrm","packuswbPrm",
145"punpckhbwPrm","punpckhwdPrm","punpckhdqPrm","packssdwPrm",
146"||punpcklqdqXrm","||punpckhqdqXrm",
147"movdPrDm","movqMrm|movdquXrm|movdqaXrm",
148--7x
149"pshufwPrmu","pshiftw!Pmu","pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu",
150"pcmpeqbPrm","pcmpeqwPrm","pcmpeqdPrm","emms|",
151nil,nil,nil,nil,
152"||haddpdXrm|haddpsXrm","||hsubpdXrm|hsubpsXrm",
153"movdDmMr|movqXrm|movdDmXr","movqMmr|movdquXmr|movdqaXmr",
154--8x
155"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
156"jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj",
157--9x
158"setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm",
159"setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm",
160--Ax
161"push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil,
162"push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm",
163--Bx
164"cmpxchgBmr","cmpxchgVmr","lssVrm","btrVmr",
165"lfsVrm","lgsVrm","movzxVrBm","movzxDrWm",
166nil,"ud2","bt!Vmu","btcVmr",
167"bsfVrm","bsrVrm","movsxVrBm","movsxDrWm",
168--Cx
169"xaddBmr","xaddVmr",
170"cmppsXrmu|cmpssXrmu|cmppdXrmu|cmpsdXrmu","movntiDmr|",
171"pinsrwPrWmu","pextrwDrPmu",
172"shufpsXrmu||shufpdXrmu","cmpxchg!Dmp",
173"bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR",
174--Dx
175"||addsubpdXrm|addsubpsXrm","psrlwPrm","psrldPrm","psrlqPrm",
176"paddqPrm","pmullwPrm",
177"|movq2dqXrMm|movqXmr|movdq2qMrXm","pmovmskbDrPm",
178"psubusbPrm","psubuswPrm","pminubPrm","pandPrm",
179"paddusbPrm","padduswPrm","pmaxubPrm","pandnPrm",
180--Ex
181"pavgbPrm","psrawPrm","psradPrm","pavgwPrm",
182"pmulhuwPrm","pmulhwPrm",
183"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","movntqMmr||movntdqXmr",
184"psubsbPrm","psubswPrm","pminswPrm","porPrm",
185"paddsbPrm","paddswPrm","pmaxswPrm","pxorPrm",
186--Fx
187"|||lddquXrm","psllwPrm","pslldPrm","psllqPrm",
188"pmuludqPrm","pmaddwdPrm","psadbwPrm","maskmovqMrm||maskmovdquXrm",
189"psubbPrm","psubwPrm","psubdPrm","psubqPrm",
190"paddbPrm","paddwPrm","padddPrm","ud",
191}
192assert(map_opc2[255] == "ud")
193
194-- Map for SSSE3 opcodes.
195local map_ssse3 = {
196["38"] = { -- [66] 0f 38 xx
197--0x
198[0]="pshufbPrm","phaddwPrm","phadddPrm","phaddswPrm",
199"pmaddubswPrm","phsubwPrm","phsubdPrm","phsubswPrm",
200"psignbPrm","psignwPrm","psigndPrm","pmulhrswPrm",
201nil,nil,nil,nil,
202--1x
203nil,nil,nil,nil,nil,nil,nil,nil,
204nil,nil,nil,nil,"pabsbPrm","pabswPrm","pabsdPrm",nil,
205},
206["3a"] = { -- [66] 0f 3a xx
207[0x0f] = "palignrPrmu",
208},
209}
210
211-- Map for FP opcodes. And you thought stack machines are simple?
212local map_opcfp = {
213-- D8-DF 00-BF: opcodes with a memory operand.
214-- D8
215[0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm",
216"fldFm",nil,"fstFm","fstpFm","fldenvDmp","fldcwWm","fnstenvDmp","fnstcwWm",
217-- DA
218"fiaddDm","fimulDm","ficomDm","ficompDm",
219"fisubDm","fisubrDm","fidivDm","fidivrDm",
220-- DB
221"fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp",
222-- DC
223"faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm",
224-- DD
225"fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm",
226-- DE
227"fiaddWm","fimulWm","ficomWm","ficompWm",
228"fisubWm","fisubrWm","fidivWm","fidivrWm",
229-- DF
230"fildWm","fisttpWm","fistWm","fistpWm",
231"fbld twordFmp","fildQm","fbstp twordFmp","fistpQm",
232-- xx C0-FF: opcodes with a pseudo-register operand.
233-- D8
234"faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf",
235-- D9
236"fldFf","fxchFf",{"fnop"},nil,
237{"fchs","fabs",nil,nil,"ftst","fxam"},
238{"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"},
239{"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"},
240{"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"},
241-- DA
242"fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil,
243-- DB
244"fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf",
245{nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil,
246-- DC
247"fadd toFf","fmul toFf",nil,nil,
248"fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf",
249-- DD
250"ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil,
251-- DE
252"faddpFf","fmulpFf",nil,{nil,"fcompp"},
253"fsubrpFf","fsubpFf","fdivrpFf","fdivpFf",
254-- DF
255nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil,
256}
257assert(map_opcfp[126] == "fcomipFf")
258
259-- Map for opcode groups. The subkey is sp from the ModRM byte.
260local map_opcgroup = {
261 arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" },
262 shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" },
263 testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" },
264 testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" },
265 inc = { "inc", "dec", "callDmp", "call farDmp",
266 "jmpDmp", "jmp farDmp", "push" },
267 sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" },
268 sgdt = { "sgdt", "sidt", "lgdt", "lidt", "smsw", nil, "lmsw", "invlpg" },
269 bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" },
270 cmpxchg = { nil, "cmpxchg8b" },
271 pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" },
272 pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" },
273 pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" },
274 pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" },
275 fxsave = { "fxsave", "fxrstor", "ldmxcsr", "stmxcsr",
276 nil, "lfenceDp", "mfenceDp", "sfenceDp" }, -- TODO: clflush.
277 prefetch = { "prefetch", "prefetchw" },
278 prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" },
279}
280
281------------------------------------------------------------------------------
282
283-- Maps for register names.
284local map_aregs = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" }
285local map_regs = {
286 B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" },
287 W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" },
288 D = map_aregs,
289 M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" },
290 X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" },
291}
292local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
293
294-- Maps for size names.
295local map_sz2n = {
296 B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16,
297}
298local map_sz2prefix = {
299 B = "byte", W = "word", D = "dword",
300 Q = "qword", -- No associated reg in 32 bit mode.
301 F = "dword", G = "qword", -- No need for sizes/register names for these two.
302 M = "qword", X = "xword",
303}
304
305------------------------------------------------------------------------------
306
307-- Output a nicely formatted line with an opcode and operands.
308local function putop(ctx, text, operands)
309 local code, pos, hex = ctx.code, ctx.pos, ""
310 for i=ctx.start,pos-1 do
311 hex = hex..format("%02X", byte(code, i, i))
312 end
313 if #hex > 16 then hex = sub(hex, 1, 16).."." end
314 if operands then text = text.." "..operands end
315 if ctx.o16 then text = "o16 "..text; ctx.o16 = false end
316 if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
317 if ctx.seg then
318 local text2, n = gsub(text, "%[", "["..ctx.seg..":")
319 if n == 0 then text = ctx.seg.." "..text else text = text2 end
320 ctx.seg = false
321 end
322 if ctx.lock then text = "lock "..text; ctx.lock = false end
323 local imm = ctx.imm
324 if imm then
325 local sym = ctx.symtab[imm]
326 if sym then text = text.."\t->"..sym end
327 end
328 ctx.out(format("%08x %-18s%s\n", ctx.addr+ctx.start, hex, text))
329 ctx.mrm = false
330 ctx.start = pos
331 ctx.imm = nil
332end
333
334-- Fallback for incomplete opcodes at the end.
335local function incomplete(ctx)
336 ctx.pos = ctx.stop+1
337 ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
338 return putop(ctx, "(incomplete)")
339end
340
341-- Fallback for unknown opcodes.
342local function unknown(ctx)
343 ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
344 return putop(ctx, "(unknown)")
345end
346
347-- Return an immediate of the specified size.
348local function getimm(ctx, pos, n)
349 if pos+n-1 > ctx.stop then return incomplete(ctx) end
350 local code = ctx.code
351 if n == 1 then
352 local b1 = byte(code, pos, pos)
353 return b1
354 elseif n == 2 then
355 local b1, b2 = byte(code, pos, pos+1)
356 return b1+b2*256
357 else
358 local b1, b2, b3, b4 = byte(code, pos, pos+3)
359 local imm = b1+b2*256+b3*65536+b4*16777216
360 ctx.imm = imm
361 return imm
362 end
363end
364
365-- Process pattern string and generate the operands.
366local function putpat(ctx, name, pat)
367 local operands, regs, sz, mode, sp, rm, sc, rx, disp, sdisp
368 local code, pos, stop = ctx.code, ctx.pos, ctx.stop
369
370 -- Chars used: 1DFGMPQRVWXacdfgijmoprsuwxyz
371 for p in gmatch(pat, ".") do
372 local x = nil
373 if p == "V" then
374 sz = ctx.o16 and "W" or "D"; ctx.o16 = false
375 regs = map_regs[sz]
376 elseif match(p, "[BWDQFGMX]") then
377 sz = p
378 regs = map_regs[sz]
379 elseif p == "P" then
380 sz = ctx.o16 and "X" or "M"; ctx.o16 = false
381 regs = map_regs[sz]
382 elseif p == "s" then
383 local imm = getimm(ctx, pos, 1); if not imm then return end
384 x = imm <= 127 and format("byte +0x%02x", imm)
385 or format("byte -0x%02x", 256-imm)
386 pos = pos+1
387 elseif p == "u" then
388 local imm = getimm(ctx, pos, 1); if not imm then return end
389 x = format("0x%02x", imm)
390 pos = pos+1
391 elseif p == "w" then
392 local imm = getimm(ctx, pos, 2); if not imm then return end
393 x = format("0x%x", imm)
394 pos = pos+2
395 elseif p == "o" then -- [offset]
396 local imm = getimm(ctx, pos, 4); if not imm then return end
397 x = format("[0x%08x]", imm)
398 pos = pos+4
399 elseif p == "i" then
400 local n = map_sz2n[sz]
401 local imm = getimm(ctx, pos, n); if not imm then return end
402 x = format(imm > 65535 and "0x%08x" or "0x%x", imm)
403 pos = pos+n
404 elseif p == "j" then
405 local n = map_sz2n[sz]
406 local imm = getimm(ctx, pos, n); if not imm then return end
407 if sz == "B" and imm > 127 then imm = imm-256
408 elseif imm > 2147483647 then imm = imm-4294967296 end
409 pos = pos+n
410 imm = imm + pos + ctx.addr
411 ctx.imm = imm
412 x = sz == "W" and format("word 0x%04x", imm%65536)
413 or format("0x%08x", imm)
414 elseif p == "R" then x = regs[byte(code, pos-1, pos-1)%8+1]
415 elseif p == "a" then x = regs[1]
416 elseif p == "c" then x = "cl"
417 elseif p == "d" then x = "dx"
418 elseif p == "1" then x = "1"
419 else
420 if not mode then
421 mode = ctx.mrm
422 if not mode then
423 if pos > stop then return incomplete(ctx) end
424 mode = byte(code, pos, pos)
425 pos = pos+1
426 end
427 rm = mode%8; mode = (mode-rm)/8
428 sp = mode%8; mode = (mode-sp)/8
429 sdisp = ""
430 if mode < 3 then
431 if rm == 4 then
432 if pos > stop then return incomplete(ctx) end
433 sc = byte(code, pos, pos)
434 pos = pos+1
435 rm = sc%8; sc = (sc-rm)/8
436 rx = sc%8; sc = (sc-rx)/8
437 if rx == 4 then rx = nil end
438 end
439 if mode > 0 or rm == 5 then
440 local dsz = mode
441 if dsz ~= 1 then dsz = 4 end
442 disp = getimm(ctx, pos, dsz); if not disp then return end
443 sdisp = (dsz == 4 or disp <= 127) and
444 format(disp > 65535 and "+0x%08x" or "+0x%x", disp) or
445 format("-0x%x", 256-disp)
446 pos = pos+dsz
447 end
448 end
449 end
450 if p == "m" then
451 if mode == 3 then x = regs[rm+1]
452 else
453 local srm, srx = map_aregs[rm+1], ""
454 if rx then
455 srm = srm.."+"
456 srx = map_aregs[rx+1]
457 if sc > 0 then srx = srx.."*"..(2^sc) end
458 end
459 if mode == 0 and rm == 5 then
460 srm = ""
461 sdisp = format("%s0x%08x", rx and "+" or "", disp)
462 end
463 x = format("[%s%s%s]", srm, srx, sdisp)
464 end
465 if mode < 3 and
466 (not match(pat, "[aRrgp]") or
467 name == "movzx" or name == "movsx") then -- Yuck.
468 x = map_sz2prefix[sz].." "..x
469 end
470 elseif p == "r" then x = regs[sp+1]
471 elseif p == "g" then x = map_segregs[sp+1]
472 elseif p == "p" then -- Suppress prefix.
473 elseif p == "f" then x = "st"..rm
474 elseif p == "x" then x = "CR"..sp
475 elseif p == "y" then x = "DR"..sp
476 elseif p == "z" then x = "TR"..sp
477 else
478 error("bad pattern `"..pat.."'")
479 end
480 end
481 if x then operands = operands and operands..","..x or x end
482 end
483 ctx.pos = pos
484 return putop(ctx, name, operands)
485end
486
487-- Forward declaration.
488local map_act
489
490-- Get a pattern from an opcode map and dispatch to handler.
491local function opcdispatch(ctx, opcmap)
492 local pos = ctx.pos
493 local opat = opcmap[byte(ctx.code, pos, pos)]
494 if not opat then return unknown(ctx) end
495 if match(opat, "%|") then -- MMX/SSE variants depending on prefix.
496 local p
497 if ctx.rep then p = ctx.rep=="rep" and "%|([^%|]*)" or "%|.-%|.-%|([^%|]*)"
498 elseif ctx.o16 then p = "%|.-%|([^%|]*)"
499 else p = "^[^%|]*" end
500 opat = match(opat, p)
501 if not opat or opat == "" then return unknown(ctx) end
502 ctx.rep = false; ctx.o16 = false
503 end
504 local name, pat, act = match(opat, "^([a-z0-9 ]*)((.?).*)")
505 ctx.pos = pos + 1
506 return map_act[act](ctx, name, pat)
507end
508
509-- Map for action codes. The key is the first char after the name.
510map_act = {
511 -- Simple opcodes without operands.
512 [""] = function(ctx, name, pat)
513 return putop(ctx, name)
514 end,
515
516 -- Operand size chars fall right through.
517 B = putpat, W = putpat, D = putpat, V = putpat,
518 F = putpat, G = putpat,
519 M = putpat, X = putpat, P = putpat,
520
521 -- Collect prefixes.
522 [":"] = function(ctx, name, pat)
523 ctx[pat == ":" and name or sub(pat, 2)] = name
524 end,
525
526 -- Select alternate opcode name when prefixed with o16.
527 ["/"] = function(ctx, name, pat)
528 local wname, rpat = match(pat, "^/([a-z0-9 ]+)(.*)")
529 if ctx.o16 then name = wname; ctx.o16 = false end
530 return putpat(ctx, name, rpat)
531 end,
532
533 -- Chain to special handler specified by name.
534 ["*"] = function(ctx, name, pat)
535 return map_act[name](ctx, name, sub(pat, 2))
536 end,
537
538 -- Use named subtable for opcode group.
539 ["!"] = function(ctx, name, pat)
540
541 local pos = ctx.pos
542 if pos > ctx.stop then return incomplete(ctx) end
543 local mrm = byte(ctx.code, pos, pos)
544 ctx.pos = pos+1
545 ctx.mrm = mrm
546
547 local opat = map_opcgroup[name][((mrm-(mrm%8))/8)%8+1]
548 if not opat then return unknown(ctx) end
549 local name, pat2 = match(opat, "^([a-z0-9 ]*)(.*)")
550 return putpat(ctx, name, pat2 ~= "" and pat2 or sub(pat, 2))
551 end,
552
553 -- Two-byte opcode dispatch.
554 opc2 = function(ctx, name, pat)
555 return opcdispatch(ctx, map_opc2)
556 end,
557
558 -- SSSE3 dispatch.
559 ssse3 = function(ctx, name, pat)
560 return opcdispatch(ctx, map_ssse3[pat])
561 end,
562
563 -- Floating point opcode dispatch.
564 fp = function(ctx, name, pat)
565
566 local pos = ctx.pos
567 if pos > ctx.stop then return incomplete(ctx) end
568 local mrm = byte(ctx.code, pos, pos)
569 ctx.pos = pos+1
570 ctx.mrm = mrm
571
572 local rm = mrm%8
573 local idx = pat*8 + ((mrm-rm)/8)%8
574 if mrm >= 192 then idx = idx + 64 end
575 local opat = map_opcfp[idx]
576 if type(opat) == "table" then opat = opat[rm+1] end
577 if not opat then return unknown(ctx) end
578 local name, pat2 = match(opat, "^([a-z0-9 ]*)(.*)")
579 return putpat(ctx, name, pat2)
580 end,
581}
582
583------------------------------------------------------------------------------
584
585-- Disassemble a block of code.
586local function disass_block(ctx, ofs, len)
587 if not ofs then ofs = 0 end
588 local stop = len and ofs+len or #ctx.code
589 ofs = ofs + 1
590 ctx.start = ofs
591 ctx.pos = ofs
592 ctx.stop = stop
593 ctx.imm = nil
594 ctx.mrm = false
595 ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
596 while ctx.pos <= stop do opcdispatch(ctx, map_opc1) end
597 if ctx.pos ~= ctx.start then incomplete(ctx) end
598end
599
600-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
601local function create_(code, addr, out)
602 local ctx = {}
603 ctx.code = code
604 ctx.addr = (addr or 0) - 1
605 ctx.out = out or io.write
606 ctx.symtab = {}
607 ctx.disass = disass_block
608 return ctx
609end
610
611-- Simple API: disassemble code (a string) at address and output via out.
612local function disass_(code, addr, out)
613 create_(code, addr, out):disass()
614end
615
616
617-- Public module functions.
618module(...)
619
620create = create_
621disass = disass_
622
diff --git a/libraries/LuaJIT-1.1.7/jit/dump.lua b/libraries/LuaJIT-1.1.7/jit/dump.lua
deleted file mode 100644
index 2287c23..0000000
--- a/libraries/LuaJIT-1.1.7/jit/dump.lua
+++ /dev/null
@@ -1,265 +0,0 @@
1----------------------------------------------------------------------------
2-- LuaJIT machine code dumper module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- Activate this module to dump the machine code for all functions
8-- immediately after they have been compiled. The disassembler
9-- output is mixed with the bytecode listing.
10--
11-- Try: luajit -j dump -e 'print "foo"'
12-- luajit -j dump=foo.dump foo.lua
13-- luajit -j off -j dump -e 'jit.compile(assert(loadfile"foo.lua")))'
14--
15-- Default output is to stderr. To redirect output to a file,
16-- pass a filename as an argument or set the environment variable
17-- "LUAJIT_DUMPFILE".
18-- Note: The file is overwritten each time you run luajit.
19--
20-- TODO: Find a way to be more selective on what to dump.
21------------------------------------------------------------------------------
22
23-- Priority for compiler pipeline. Must run after backend (negative)
24-- and should be even because we only catch successful compiles.
25local PRIORITY = -98
26
27-- Cache some library functions and objects.
28local jit = require("jit")
29assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
30local jutil = require("jit.util")
31local type, format, gsub = type, string.format, string.gsub
32local bytecode, const = jutil.bytecode, jutil.const
33local getinfo = debug.getinfo
34local stdout, stderr = io.stdout, io.stderr
35
36-- Load the right disassembler.
37local dis = require("jit.dis_"..jit.arch)
38local discreate, disass_ = dis.create, dis.disass
39
40-- Turn compilation off for the whole module. LuaJIT would do that anyway.
41jit.off(true, true)
42
43-- Separator line.
44local sepline = "-------------------------------"
45
46-- Map JSUB indices to names.
47-- CHECK: must match the order in ljit_x86.h. Regenerate with:
48-- grep '^ *JSUB_[^_].*,' ljit_x86.h | sed -e 's/^ *JSUB_/ "/' -e 's/,.*/",/'
49local jsubnames = {
50 "STACKPTR",
51 "GATE_LJ",
52 "GATE_JL",
53 "GATE_JC",
54 "GROW_STACK",
55 "GROW_CI",
56 "GATE_JC_PATCH",
57 "GATE_JC_DEBUG",
58 "DEOPTIMIZE_CALLER",
59 "DEOPTIMIZE",
60 "DEOPTIMIZE_OPEN",
61 "HOOKINS",
62 "GCSTEP",
63 "STRING_SUB3",
64 "STRING_SUB2",
65 "HOOKCALL",
66 "HOOKRET",
67 "METACALL",
68 "METATAILCALL",
69 "BARRIERF",
70 "GETGLOBAL",
71 "GETTABLE_KSTR",
72 "GETTABLE_STR",
73 "BARRIERBACK",
74 "SETGLOBAL",
75 "SETTABLE_KSTR",
76 "SETTABLE_STR",
77 "GETTABLE_KNUM",
78 "GETTABLE_NUM",
79 "SETTABLE_KNUM",
80 "SETTABLE_NUM",
81 "LOG2_TWORD",
82 "CONCAT_STR2",
83}
84
85-- Generate map from JSUB addresses to JSUB names.
86local jsubmap = {}
87do
88 local jsubmcode = jutil.jsubmcode
89 for pc=0,100000 do
90 local addr = jsubmcode(pc)
91 if not addr then break end
92 jsubmap[addr] = jsubnames[pc+1] or "JSUB#"..pc
93 end
94end
95
96-- Pretty-print a constant.
97local function conststr(func, idx)
98 local k = const(func, idx)
99 if k == nil then return "nil"
100 elseif k == true then return "true"
101 elseif k == false then return "false"
102 elseif type(k) == "string" then
103 if #k > 10 then return format('"%.10s"~', k)
104 else return '"'..k..'"' end
105 else return k.."" end
106end
107
108-- Pretty-print a bytecode instruction (one or two lines).
109local function bytecodeout(out, func, pc)
110 local op, a, b, c = bytecode(func, pc)
111 if not op then
112 return true
113 elseif op == "JMP" then
114 out:write(format("\n--%04d-- JMP => %04d", pc, pc+1+b))
115 elseif op == "FORLOOP" or op == "FORPREP" then
116 out:write(format("\n--%04d-- %-9s %3d => %04d", pc, op, a, pc+1+b))
117 else
118 out:write(format("\n--%04d-- %-9s %3d %4s %4s",
119 pc, op, a, b or "", c or ""))
120 if b and b < 0 then out:write(" ; ", conststr(func, b)) end
121 if c and c < 0 then out:write(" ; ", conststr(func, c)) end
122 end
123end
124
125-- Dump machine code and mix it with the bytecode listing.
126local function dumpfunc(func, out, deopt)
127 if not out then out = stderr end
128 local info = getinfo(func, "S")
129
130 -- Don't bother checking for the right blocks to dump.
131 -- Dump the main block (if not deopt) and always all deopt blocks.
132 for block=deopt and 2 or 1,1000000 do
133 local addr, code, mfmiter = jutil.mcode(func, block)
134 if not addr then
135 if code then return code end -- Not compiled: return status.
136 break -- No more blocks to dump.
137 end
138
139 -- Print header.
140 out:write(sepline, " ", info.source, ":", info.linedefined)
141 if block ~= 1 then out:write(" DEOPT block ", block) end
142
143 -- Create disassembler context.
144 local ctx = discreate(code, addr, function(s) out:write(s) end)
145 ctx.symtab = jsubmap
146
147 -- Dump an mcode block.
148 local pc, ofs = 1, 0
149 local len, isdeopt = mfmiter()
150 if isdeopt then pc = len; len = 0
151 elseif block ~= 1 then break end -- Stop before next main block.
152 for t, m in mfmiter do
153 if t == "COMBINE" then
154 bytecodeout(out, func, pc)
155 else
156 if len ~= 0 then
157 out:write("\n")
158 if len > 0 then
159 ctx:disass(ofs, len)
160 ofs = ofs + len
161 else
162 out:write(format("%08x ** deoptimized\n", addr+ofs))
163 ofs = ofs - len
164 end
165 len = 0
166 end
167 if type(t) == "number" then
168 if m then
169 if isdeopt then
170 pc = t - 1
171 else
172 bytecodeout(out, func, pc)
173 len = -t
174 end
175 else
176 len = t
177 if bytecodeout(out, func, pc) then break end
178 end
179 end
180 end
181 pc = pc + 1
182 end
183 if len and len ~= 0 then
184 out:write(sepline, " tail code\n")
185 ctx:disass(ofs, len)
186 end
187 end
188
189 -- Print footer.
190 out:write(sepline, "\n")
191 out:flush()
192end
193
194-- Dump the internal JIT subroutines.
195local function dumpjsub_(out)
196 if not out then out = stderr end
197 local addr, code = jutil.jsubmcode()
198
199 -- Create disassembler context.
200 local ctx = discreate(code, addr, function(s) out:write(s) end)
201 ctx.symtab = jsubmap
202
203 -- Collect addresses and sort them.
204 local t = {}
205 for addr in pairs(jsubmap) do t[#t+1] = addr end
206 t[#t+1] = addr + #code
207 table.sort(t)
208
209 -- Go through the addresses in ascending order.
210 local ofs = addr
211 for i=2,#t do
212 local next = t[i]
213 out:write("\n->", jsubmap[ofs], ":\n") -- Output label for JSUB.
214 ctx:disass(ofs-addr, next-ofs) -- Disassemble corresponding code block.
215 ofs = next
216 end
217 out:flush()
218end
219
220
221-- Active flag and output file handle.
222local active, out
223
224-- Dump handler for compiler pipeline.
225local function h_dump(st)
226 local ok, err = pcall(dumpfunc, st.func, out, st.deopt)
227 if not ok then
228 stderr:write("\nERROR: jit.dump disabled: ", err, "\n")
229 jit.attach(h_dump) -- Better turn ourselves off after a failure.
230 if out and out ~= stdout then out:close() end
231 out = nil
232 active = nil
233 end
234end
235
236-- Detach dump handler from compiler pipeline.
237local function dumpoff()
238 if active then
239 active = false
240 jit.attach(h_dump)
241 if out and out ~= stdout then out:close() end
242 out = nil
243 end
244end
245
246-- Open the output file and attach dump handler to compiler pipeline.
247local function dumpon(filename)
248 if active then dumpoff() end
249 local outfile = filename or os.getenv("LUAJIT_DUMPFILE")
250 out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w")))
251 jit.attach(h_dump, PRIORITY)
252 active = true
253end
254
255
256-- Public module functions.
257module(...)
258
259disass = disass_
260dump = dumpfunc
261dumpjsub = dumpjsub_
262on = dumpon
263off = dumpoff
264start = dumpon -- For -j command line option.
265
diff --git a/libraries/LuaJIT-1.1.7/jit/dumphints.lua b/libraries/LuaJIT-1.1.7/jit/dumphints.lua
deleted file mode 100644
index 4a64676..0000000
--- a/libraries/LuaJIT-1.1.7/jit/dumphints.lua
+++ /dev/null
@@ -1,239 +0,0 @@
1----------------------------------------------------------------------------
2-- LuaJIT hints dumper module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- Activate this module to dump the bytecode and the hints from
8-- the optimizer for all functions to be compiled.
9--
10-- Try: luajit -O -j dumphints -e 'return 1'
11--
12-- Default output is to stderr. To redirect output to a file,
13-- pass a filename as an argument or set the environment variable
14-- "LUAJIT_DUMPHINTSFILE".
15-- Note: The file is overwritten each time you run luajit.
16--
17-- TODO: Find a way to be more selective on what to dump.
18------------------------------------------------------------------------------
19
20-- Priority for compiler pipeline. Should run before backend (positive)
21-- and should be even because we only catch successful compiles.
22local PRIORITY = 10
23
24-- Cache some library functions and objects.
25local jit = require("jit")
26assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
27local jutil = require("jit.util")
28local type, pairs, format = type, pairs, string.format
29local bytecode, const = jutil.bytecode, jutil.const
30local hints, fhints = jutil.hints, jutil.fhints
31local stdout, stderr = io.stdout, io.stderr
32
33-- Turn compilation off for the whole module. LuaJIT would do that anyway.
34jit.off(true, true)
35
36-- Separator line.
37local sepline = "-------------------------------"
38
39
40-- Pretty-print a constant.
41local function conststr(func, idx)
42 local k = const(func, idx)
43 if k == nil then return "nil"
44 elseif k == true then return "true"
45 elseif k == false then return "false"
46 elseif type(k) == "string" then
47 if #k > 10 then return format('"%.10s"~', k)
48 else return '"'..k..'"' end
49 else return k.."" end
50end
51
52-- Pretty-print a bytecode instruction.
53local function bytecodeline(func, pc, flag)
54 local op, a, b, c = bytecode(func, pc)
55 if not op then return end
56 if op == "JMP" then
57 return format("\n%04d %s JMP => %04d", pc, flag, pc+1+b)
58 end
59 if op == "FORLOOP" or op == "FORPREP" then
60 return format("\n%04d %s %-9s %3d => %04d", pc, flag, op, a, pc+1+b)
61 end
62 local s = format("\n%04d %s %-9s %3d %4s %4s",
63 pc, flag, op, a, b or "", c or "")
64 if b and b < 0 then s = s.." ; "..conststr(func, b) end
65 if c and c < 0 then s = s.." ; "..conststr(func, c) end
66 return s
67end
68
69-- Precompute inverse hints table.
70local invhints = {}
71for k,v in pairs(hints) do invhints[v] = k end
72
73-- The inverse resolver for inline functions is loaded on demand.
74local getname
75
76-- Helper functions to pretty-print hints.
77local function typehint(h, v, st, pc)
78 if st[pc+hints.INLINE] then return "" end
79 local tp = type(v)
80 if tp == "function" then
81 tp = debug.getinfo(v, "S").what
82 elseif tp == "number" and v % 1 == 0 then
83 tp = "integer"
84 elseif v == false then
85 tp = "mixed"
86 end
87 return " #"..h.."("..tp..")"
88end
89
90local hintprint = {
91 COMBINE = function(h, v, st, pc)
92 if v == false then return "" end -- Dead instructions are already marked.
93 end,
94 TYPE = typehint,
95 TYPEKEY = typehint,
96 INLINE = function(h, v, st, pc)
97 if not getname then getname = require("jit.opt_inline").getname end
98 return " #INLINE("..getname(st[pc+hints.TYPE], v)..")"
99 end,
100}
101
102-- Generate range string from table: pc[-pc] [,...]
103local function rangestring(t)
104 local s = ""
105 for i,range in ipairs(t) do
106 if i ~= 1 then s = s.."," end
107 local pc = range % 65536
108 range = (range - pc) / 65536
109 s = s..pc
110 if range ~= 0 then s = s..(-(pc+range)) end
111 end
112 return s
113end
114
115-- Dump instructions and hints for a (to be compiled) function.
116local function dumphints(st, out)
117 if not out then out = stderr end
118 local func = st.func
119 local COMBINE = hints.COMBINE
120
121 -- Need to recompute branch targets (not part of hints).
122 local target = {}
123 for pc=1,1e6 do
124 local op, a, b, c = bytecode(func, pc)
125 if not op then break end
126 if op == "JMP" or op == "FORLOOP" then
127 local t = pc+1+b
128 if st[pc+COMBINE] ~= false then target[t] = true end
129 elseif op == "LOADBOOL" and c ~= 0 then
130 target[pc+2] = true
131 end
132 end
133
134 -- Map hints to bytecode instructions.
135 local hintstr = {}
136 for k,v in pairs(st) do
137 -- CHECK: must match hint shift in ljit_hints.h:JIT_H2NUM().
138 if type(k) == "number" and k >= 65536 then
139 local pc = k % 65536
140 if pc > 0 then
141 k = k - pc
142 local h = invhints[k] or (k/65536)
143 local hp = hintprint[h]
144 local s = hp and hp(h, v, st, pc) or (" #"..h)
145 local hs = hintstr[pc]
146 hintstr[pc] = hs and (hs..s) or s
147 end
148 end
149 end
150
151 -- Write header.
152 local info = debug.getinfo(func, "S")
153 out:write(sepline, " ", info.source, ":", info.linedefined)
154
155 -- Write function hints.
156 for k,v in pairs(fhints) do
157 if st[v] then out:write("\n#", k) end
158 end
159
160 -- Write instruction hints and bytecode.
161 local function dumprange(firstpc, lastpc)
162 for pc=firstpc,lastpc do
163 local prefix = " "
164 if st[pc+COMBINE] == false then prefix = "**"
165 elseif target[pc] then prefix = "=>" end
166 local line = bytecodeline(func, pc, prefix)
167 if not line then break end
168 local h = hintstr[pc]
169 if h then
170 out:write(format("%-40s %s", line, h))
171 else
172 out:write(line)
173 end
174 end
175 end
176
177 -- Handle deoptimization range table.
178 local t = st.deopt
179 if t then
180 out:write(" DEOPT=", rangestring(t))
181 for i,range in ipairs(t) do
182 if i ~= 1 then out:write("\n----") end
183 local pc = range % 65536
184 range = (range - pc) / 65536
185 dumprange(pc, pc+range)
186 end
187 else
188 dumprange(1, 1000000)
189 end
190
191 -- Write footer.
192 out:write("\n", sepline, "\n")
193 out:flush()
194end
195
196
197-- Active flag and output file handle.
198local active, out
199
200-- Dump hints handler for compiler pipeline.
201local function h_dumphints(st)
202 local ok, err = pcall(dumphints, st, out)
203 if not ok then
204 stderr:write("\nERROR: jit.dumphints disabled: ", err, "\n")
205 jit.attach(h_dumphints) -- Better turn ourselves off after a failure.
206 if out and out ~= stdout then out:close() end
207 out = nil
208 active = nil
209 end
210end
211
212-- Detach dump handler from compiler pipeline.
213local function dumphintsoff()
214 if active then
215 active = false
216 jit.attach(h_dumphints)
217 if out and out ~= stdout then out:close() end
218 out = nil
219 end
220end
221
222-- Open the output file and attach dump handler to compiler pipeline.
223local function dumphintson(filename)
224 if active then dumphintsoff() end
225 local outfile = filename or os.getenv("LUAJIT_DUMPHINTSFILE")
226 out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w")))
227 jit.attach(h_dumphints, PRIORITY)
228 active = true
229end
230
231
232-- Public module functions.
233module(...)
234
235dump = dumphints
236on = dumphintson
237off = dumphintsoff
238start = dumphintson -- For -j command line option.
239
diff --git a/libraries/LuaJIT-1.1.7/jit/opt.lua b/libraries/LuaJIT-1.1.7/jit/opt.lua
deleted file mode 100644
index 5fe0f34..0000000
--- a/libraries/LuaJIT-1.1.7/jit/opt.lua
+++ /dev/null
@@ -1,508 +0,0 @@
1----------------------------------------------------------------------------
2-- LuaJIT optimizer.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- This module contains a simple optimizer that generates some hints for
8-- the compiler backend.
9--
10-- Compare: luajit -j dump -e 'return 1'
11-- with: luajit -O -j dumphints -j dump -e 'return 1'
12--
13-- This module uses a very simplistic (but fast) abstract interpretation
14-- algorithm. It mostly ignores control flow and/or basic block boundaries.
15-- Thus the results of the analysis are really only predictions (e.g. about
16-- monomorphic use of operators). The backend _must_ check all contracts
17-- (e.g. verify the object type) and use a (polymorphic) fallback or
18-- deoptimization in case a contract is broken.
19--
20-- Although simplistic, the generated hints are pretty accurate. Note that
21-- some hints are really definitive and don't need to be checked (like
22-- COMBINE or FOR_STEP_K).
23--
24-- TODO: Try MFP with an extended lattice. But it's unclear whether the
25-- added complexity really pays off with the current backend.
26------------------------------------------------------------------------------
27
28-- Priority for compiler pipeline. Right in the middle before the backend.
29local PRIORITY = 50
30
31-- Default optimizer level, i.e. what you get with -O.
32-- Caveat: this may change in the future when more optimizations are added.
33local OPTLEVEL = 2
34
35-- Heuristic limits for what the compiler should reasonably handle.
36-- Functions outside these limits are unlikely to be run more than once.
37-- Maybe a bit on the generous side. Check ljit.h for backend limits, too.
38-- TODO: make it depend on the bytecode distribution, too.
39local LIMITS = {
40 bytecodes = 4000,
41 stackslots = 150,
42 params = 20,
43 consts = 200,
44 subs = 30,
45}
46
47-- Cache some library functions and objects.
48local jit = require("jit")
49assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
50local jutil = require("jit.util")
51local type, rawget, next, pcall = type, rawget, next, pcall
52local bytecode, const = jutil.bytecode, jutil.const
53local hints, fhints = jutil.hints, jutil.fhints
54local getmetatable = getmetatable
55
56-- Turn compilation off for the whole module. LuaJIT would do that anyway.
57jit.off(true, true)
58
59-- Default optimizer level after loading. But -O runs setlevel(), too.
60local optlevel = -1
61
62
63-- Use iterative path marking to mark live instructions and branch targets.
64local function marklive(func)
65 local live, work, workn, pc = {}, {}, 0, 1
66 repeat
67 repeat
68 local op, a, b, c, test = bytecode(func, pc)
69 live[pc] = true
70 pc = pc + 1
71 if op == "JMP" then
72 pc = pc + b
73 live[-pc] = true
74 elseif op == "FORLOOP" then
75 local mpc = -pc
76 live[mpc - b] = true
77 live[mpc] = true
78 elseif op == "RETURN" then
79 break
80 elseif test then
81 local fpc = pc + 1
82 -- No need for fallthrough target mark live[-fpc] in our analysis.
83 if not live[fpc] then -- Add fallthrough path to work list.
84 workn = workn + 1
85 work[workn] = fpc
86 end
87 elseif op == "CLOSURE" then
88 pc = pc + jutil.closurenup(func, b) -- Do not mark pseudo-ins live.
89 elseif op == "LOADBOOL" and c ~= 0 then
90 pc = pc + 1
91 live[-pc] = true
92 elseif op == "SETLIST" and c == 0 then
93 pc = pc + 1 -- Do not mark pseudo-ins live.
94 end
95 until live[pc]
96 if workn == 0 then return live end -- Return if work list is empty.
97 pc = work[workn] -- Else fetch next path to mark from work list.
98 workn = workn - 1
99 until false
100end
101
102
103-- Empty objects.
104local function empty() end
105
106-- Dummy function to set call hints. Replaced when jit.opt_inline is loaded.
107local function callhint(st, slot, pc, base, narg, nres)
108 st[pc+hints.TYPE] = slot[base]
109 for i=base,base+nres-1 do slot[i] = nil end
110end
111
112-- Set TYPE hint, but only for numbers, strings or tables.
113local function typehint(st, pc, o)
114 local tp = type(o)
115 if tp == "number" or tp == "string" or tp == "table" then
116 st[pc+hints.TYPE] = o
117 end
118end
119
120-- Set TYPE and TYPEKEY hints for table operations.
121local function tablehint(st, slot, pc, t, kslot)
122 local tp = type(t)
123 if tp == "table" or tp == "userdata" then st[pc+hints.TYPE] = t end
124 if kslot >= 0 then -- Don't need this hint for constants.
125 local key = slot[kslot]
126 local tp = type(key)
127 if tp == "number" or tp == "string" then st[pc+hints.TYPEKEY] = key end
128 end
129end
130
131-- Try to lookup a value. Guess the value or at least the value type.
132local function trylookup(st, t, k)
133 if k == nil then return nil end
134 if type(t) == "table" then
135 local v = rawget(t, k)
136 if v ~= nil then return v end
137 end
138 local mt = getmetatable(t)
139 if type(mt) == "table" then
140 -- One __index level is enough for our purposes.
141 local it = rawget(mt, "__index")
142 if type(it) == "table" then
143 local v = rawget(it, k)
144 if v ~= nil then return v end
145 end
146 end
147 local v = st.tableval[t] -- Resort to a generic guess.
148 if v == nil and type(t) == "table" then v = next(t) end -- Getting desperate.
149 return v
150end
151
152-- Check whether the previous instruction sets a const.
153local function prevconst(st, slot, pc, reg)
154 if st.live[-pc] == nil then -- Current instruction must not be a target.
155 local op, ka, kb = bytecode(st.func, pc-1)
156 if ka == reg and (op == "LOADK" or op == "LOADBOOL" or
157 (op == "LOADNIL" and kb == reg)) then
158 return true, slot[reg]
159 end
160 end
161end
162
163-- Common handler for arithmetic and comparison opcodes.
164local function arithop(st, slot, pc, a, b, c, op)
165 local sb, sc = slot[b], slot[c]
166 if sb == nil then sb = sc elseif sc == nil then sc = sb end
167 local tb, tc = type(sb), type(sc)
168 if tb == tc then
169 if tb == "number" then -- Improve the guess for numbers.
170 if op == "DIV" or sb % 1 ~= 0 or sc % 1 ~= 0 then
171 sb = 0.5 -- Probably a non-integral number.
172 else
173 sb = 1 -- Optimistic guess.
174 end
175 end
176 if sb ~= nil then st[pc+hints.TYPE] = sb end
177 else
178 st[pc+hints.TYPE] = false -- Marker for mixed types.
179 end
180 if op ~= "LT" and op ~= "LE" then
181 slot[a] = sb -- Assume coercion to 1st type if different.
182 end
183end
184
185-- Common handler for TEST and TESTSET.
186local function testop(st, slot, pc, a, b, c)
187 -- Optimize the 'expr and k1 or k2' idiom.
188 local ok, k = prevconst(st, slot, pc, b)
189 if k and a == b then
190 st[pc+hints.COMBINE] = false -- Kill the TEST/TESTSET.
191 if c == 0 then st.live[pc+1] = nil end -- Kill the JMP.
192 end
193 slot[a] = slot[b]
194end
195
196-- Dispatch table for opcode handlers.
197local handler = {
198 MOVE = function(st, slot, pc, a, b, c)
199 slot[a] = slot[b]
200 end,
201
202 LOADK = function(st, slot, pc, a, b, c)
203 slot[a] = const(st.func, b)
204 end,
205
206 LOADBOOL = function(st, slot, pc, a, b, c)
207 slot[a] = (b == 1)
208 end,
209
210 LOADNIL = function(st, slot, pc, a, b, c)
211 for i=a,b do slot[i] = nil end
212 end,
213
214 GETUPVAL = function(st, slot, pc, a, b, c)
215 slot[a] = jutil.upvalue(st.func, b)
216 end,
217
218 GETGLOBAL = function(st, slot, pc, a, b, c)
219 slot[a] = trylookup(st, st.stats.env, const(st.func, b))
220 end,
221
222 GETTABLE = function(st, slot, pc, a, b, c)
223 local t = slot[b]
224 tablehint(st, slot, pc, t, c)
225 slot[a] = trylookup(st, t, slot[c])
226 end,
227
228 SETGLOBAL = empty,
229
230 SETUPVAL = empty, -- TODO: shortcut -- but this is rare?
231
232 SETTABLE = function(st, slot, pc, a, b, c)
233 local t = slot[a]
234 tablehint(st, slot, pc, t, b)
235 if type(t) == "table" or type(t) == "userdata" then -- Must validate setkey.
236 local val = slot[c]
237 if val ~= nil then st.tableval[t] = val end
238 end
239 end,
240
241 NEWTABLE = function(st, slot, pc, a, b, c)
242 slot[a] = {} -- Need unique tables for indexing st.tableval.
243 end,
244
245 SELF = function(st, slot, pc, a, b, c)
246 local t = slot[b]
247 tablehint(st, slot, pc, t, c)
248 slot[a+1] = t
249 slot[a] = trylookup(st, t, slot[c])
250 end,
251
252 ADD = arithop, SUB = arithop, MUL = arithop, DIV = arithop,
253 MOD = arithop, POW = arithop, LT = arithop, LE = arithop,
254
255 UNM = function(st, slot, pc, a, b, c)
256 return arithop(st, slot, pc, a, b, b, "UNM")
257 end,
258
259 NOT = function(st, slot, pc, a, b, c)
260 slot[a] = true
261 end,
262
263 LEN = function(st, slot, pc, a, b, c)
264 typehint(st, pc, slot[b])
265 slot[a] = 1
266 end,
267
268 CONCAT = function(st, slot, pc, a, b, c)
269 local mixed
270 local sb = slot[b]
271 for i=b+1,c do
272 local si = slot[i]
273 if sb == nil then
274 sb = si
275 elseif si ~= nil and type(sb) ~= type(si) then
276 mixed = true
277 break
278 end
279 end
280 if sb == nil then
281 sb = ""
282 else
283 st[pc+hints.TYPE] = not mixed and sb or false
284 if type(sb) == "number" then sb = "" end
285 end
286 slot[a] = sb -- Assume coercion to 1st type (if different) or string.
287 end,
288
289 JMP = function(st, slot, pc, a, b, c)
290 if b >= 0 then -- Kill JMPs across dead code.
291 local tpc = pc + b
292 while not st.live[tpc] do tpc = tpc - 1 end
293 if tpc == pc then st[pc+hints.COMBINE] = false end
294 end
295 end,
296
297 EQ = function(st, slot, pc, a, b, c)
298 if b >= 0 and c >= 0 then typehint(st, pc, slot[b] or slot[c]) end
299 end,
300
301 TEST = function(st, slot, pc, a, b, c)
302 return testop(st, slot, pc, a, a, c)
303 end,
304
305 TESTSET = testop,
306
307 CALL = function(st, slot, pc, a, b, c)
308 callhint(st, slot, pc, a, b-1, c-1)
309 end,
310
311 TAILCALL = function(st, slot, pc, a, b, c)
312 callhint(st, slot, pc, a, b-1, -1)
313 end,
314
315 RETURN = function(st, slot, pc, a, b, c)
316 if b == 2 and prevconst(st, slot, pc, a) then
317 st[pc-1+hints.COMBINE] = true -- Set COMBINE hint for prev. instruction.
318 end
319 end,
320
321 FORLOOP = empty,
322
323 FORPREP = function(st, slot, pc, a, b, c)
324 local ok, step = prevconst(st, slot, pc, a+2)
325 if type(step) == "number" then
326 st[pc+hints.FOR_STEP_K] = step
327 end
328 local nstart, nstep = slot[a], slot[a+2]
329 local tnstart, tnstep = type(nstart), type(nstep)
330 local ntype = ((tnstart == "number" and nstart % 1 ~= 0) or
331 (tnstep == "number" and nstep % 1 ~= 0)) and 0.5 or 1
332 slot[a+3] = ntype
333 if tnstart == "number" and tnstep == "number" and
334 type(slot[a+1]) == "number" then
335 st[pc+hints.TYPE] = ntype
336 end
337 end,
338
339 -- TFORLOOP is at the end of the loop. Setting slots would be pointless.
340 -- Inlining is handled by the corresponding iterator constructor (CALL).
341 TFORLOOP = function(st, slot, pc, a, b, c)
342 st[pc+hints.TYPE] = slot[a]
343 end,
344
345 SETLIST = function(st, slot, pc, a, b, c)
346 -- TODO: if only (numeric) const: shortcut (+ nobarrier).
347 local t = slot[a]
348 -- Very imprecise. But better than nothing.
349 if type(t) == "table" then st.tableval[t] = slot[a+1] end
350 end,
351
352 CLOSE = empty,
353
354 CLOSURE = function(st, slot, pc, a, b, c)
355 slot[a] = empty
356 if st.noclose then
357 local nup = jutil.closurenup(st.func, b)
358 for i=pc+1,pc+nup do
359 local op = bytecode(st.func, i)
360 if op == "MOVE" then
361 st.noclose = false
362 return
363 end
364 end
365 end
366 end,
367
368 VARARG = function(st, slot, pc, a, b, c)
369 local params = st.stats.params
370 for i=1,b do slot[a+i-1] = st[params+i] end
371 end,
372}
373
374-- Generate some hints for the compiler backend.
375local function optimize(st)
376 -- Deoptimization is simple: just don't generate any hints. :-)
377 if st.deopt then return end
378
379 local func = st.func
380 local stats = jutil.stats(func)
381 if not stats then return jutil.status.COMPILER_ERROR end -- Eh?
382
383 -- Check limits.
384 if stats.bytecodes > LIMITS.bytecodes or
385 stats.stackslots > LIMITS.stackslots or
386 stats.params > LIMITS.params or
387 stats.consts > LIMITS.consts or
388 stats.subs > LIMITS.subs then
389 return jutil.status.TOOLARGE
390 end
391
392 -- Mark live instructions (live[pc]) and branch targets (live[-pc]).
393 local live = marklive(func)
394
395 -- Handlers need access to some temporary state fields.
396 st.noclose = true
397 st.stats = stats
398 st.live = live
399 st.tableval = { [stats.env] = empty } -- Guess: unknown globals are functions.
400
401 -- Initialize slots with argument hints and constants.
402 local slot = {}
403 for i=1,stats.params do slot[i-1] = st[i] end
404 for i=-1,-256,-1 do -- No need to copy non-RK-able consts.
405 local k, ok = const(func, i)
406 if not ok then break end
407 slot[i] = k
408 end
409
410 -- Step through all live instructions, update slots and add hints.
411 for pc=1,stats.bytecodes do
412 if live[pc] then
413 local op, a, b, c, test = bytecode(func, pc)
414 handler[op](st, slot, pc, a, b, c, op)
415 else
416 st[pc+hints.COMBINE] = false -- Dead instruction hint.
417 end
418 end
419
420 -- Update function hints.
421 if st.noclose then st[fhints.NOCLOSE] = true end
422
423 -- Clear temporary state fields.
424 st.noclose = nil
425 st.stats = nil
426 st.live = nil
427 st.tableval = nil
428end
429
430
431-- Active flags.
432local active, active_opt_inline
433
434-- Handler for compiler pipeline.
435local function h_opt(st)
436 if optlevel <= 0 then return end
437 local ok, err = pcall(optimize, st)
438 if not ok then
439 io.stderr:write("\nERROR: jit.opt disabled: ", err, "\n")
440 jit.attach(h_opt) -- Better turn ourselves off after a failure.
441 active = nil
442 else
443 if err then return err end
444 end
445end
446
447-- Load add-on module.
448local function loadaddon(opt)
449 local name, val = string.match(opt, "^(.-)=(.*)$") -- Strip value.
450 if not name then name = opt end
451 name = "jit.opt_"..name
452 local ok, mod = pcall(require, name)
453 if not ok then
454 -- Return error if not installed, but propagate other errors.
455 if string.sub(mod, 1, 7) ~= "module " then error(mod, 0) end
456 return "optimizer add-on module "..name.." not found"
457 end
458 mod.start(val)
459end
460
461-- Attach optimizer and set optimizer level or load add-on module.
462local function setlevel_(opt)
463 -- Easier to always attach the optimizer (even for -O0).
464 if not active then
465 jit.attach(h_opt, PRIORITY)
466 active = true
467 end
468
469 -- Parse -O<level> or -O<name[=value]>.
470 if opt == nil or opt == "" then
471 optlevel = OPTLEVEL
472 else
473 local level = tonumber(opt) -- Numeric level?
474 if level then
475 if level < 0 or level % 1 ~= 0 then
476 error("bad optimizer level", 0)
477 end
478 optlevel = level
479 else
480 if optlevel == -1 then optlevel = OPTLEVEL end
481 local err = loadaddon(opt)
482 if err then error(err, 0) end
483 end
484 end
485
486 -- Load add-on module for inlining functions for -O2 and above.
487 if not active_opt_inline and optlevel >= 2 then
488 loadaddon("inline") -- Be silent if not installed.
489 active_opt_inline = true -- Try this only once.
490 end
491end
492
493
494-- Public module functions.
495module(...)
496
497-- Callback to allow attaching a call hinter. Used by jit.opt_inline.
498function attach_callhint(f)
499 callhint = f
500end
501
502function getlevel()
503 return optlevel
504end
505
506setlevel = setlevel_
507start = setlevel_ -- For -O command line option.
508
diff --git a/libraries/LuaJIT-1.1.7/jit/opt_inline.lua b/libraries/LuaJIT-1.1.7/jit/opt_inline.lua
deleted file mode 100644
index cc19bf4..0000000
--- a/libraries/LuaJIT-1.1.7/jit/opt_inline.lua
+++ /dev/null
@@ -1,397 +0,0 @@
1----------------------------------------------------------------------------
2-- LuaJIT optimizer add-on module for function inlining.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- This is a simple framework for C function signature maps.
8-- It helps with type propagation and C function inlining.
9--
10-- This module is automatically loaded with -O2 and above.
11-- By default most standard library functions are added.
12--
13-- TODO: generalize it, e.g. for back propagation (i.e. arg types).
14-- TODO: extend it for Lua functions (but need to analyze them before use).
15------------------------------------------------------------------------------
16
17-- Cache some library functions and objects.
18local jit = require("jit")
19assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
20local jutil = require("jit.util")
21local type, rawget, next = type, rawget, next
22local hints, fhints = jutil.hints, jutil.fhints
23local sub, match, gsub = string.sub, string.match, string.gsub
24
25-- Turn compilation off for the whole module. LuaJIT would do that anyway.
26jit.off(true, true)
27
28-- Prototypical objects used for type hints.
29local TABLE = {}
30local CFUNC = collectgarbage -- Pretty sure this is never inlined.
31
32
33-- Map from C closures to signatures. Cannot use a weak table.
34-- Closures must be kept alive because inlining checks against their addrs.
35local map_sign = {}
36
37-- For jit.dumphints: get printable name for TYPE hint: "#INLINE(foo.bar)".
38local function getname_(f, idx)
39 local sign = map_sign[f]
40 if sign then
41 local libname, name = sign.libname, sign.name
42 if libname then
43 return libname.."."..name
44 else
45 return name
46 end
47 elseif idx == 0 then
48 return "recursive"
49 else
50 return "?"
51 end
52end
53
54-- Name, base table and running index for convenience functions.
55-- CHECK: the library index and the order below must match with ljit_hints.h
56local flibname, flib, fidx
57
58local function fadd(name, results, args, handler)
59 local f = rawget(flib, name)
60 if f then
61 map_sign[f] = {
62 libname = flibname, name = name, idx = fidx,
63 results = results, args = args, handler = handler,
64 }
65 end
66 if fidx then fidx = fidx + 1 end
67end
68
69local function faddf(name, f, results, args, handler)
70 map_sign[f] = {
71 libname = flibname, name = name, idx = fidx,
72 results = results, args = args, handler = handler,
73 }
74 if fidx then fidx = fidx + 1 end
75end
76
77
78-- Signature handler: copy first argument to first result.
79local function copyfirst(st, slot, pc, base, narg, nres)
80 slot[base] = slot[base+1]
81end
82
83-- Helper for iterators: check if the function is an iterator constructor.
84--
85-- 'for ivars in func(args) do body end'
86--
87-- ...load func+args...
88-- CALL func <-- pc
89-- JMP fwd ---+
90-- back: | <--+
91-- ...body... | |
92-- fwd: <--+ |
93-- TFORLOOP ivars | <-- tforpc
94-- JMP back ---+
95--
96local function itercheck(st, slot, pc, base, idx)
97 if idx then
98 local bytecode, func = jutil.bytecode, st.func
99 local op, _, fwd = bytecode(func, pc+1)
100 if op == "JMP" then
101 local tforpc = pc+2+fwd
102 local op, tfbase, _, tfnres = bytecode(func, tforpc)
103 if op == "TFORLOOP" and tfbase == base and tfnres <= 2 then
104 local op, _, back = bytecode(func, tforpc+1)
105 if op == "JMP" and fwd+back == -2 then
106 -- Must set inlining hint for TFORLOOP instruction here.
107 st[tforpc+hints.INLINE] = idx -- Serves as iterator index, too.
108 return -- Inline it.
109 end
110 end
111 end
112 end
113 slot[base] = CFUNC -- Better make it different from pairs.
114 return true -- Better not inline it, if not used in a for statement.
115end
116
117-- Helper for pairs/next: guess result types for standard table iterator.
118local function guessnext(st, slot, base, dest)
119 local t, k, v = slot[base+1]
120 if type(t) == "table" then
121 k, v = next(t)
122 if v == nil then v = st.tableval[t] end
123 end
124 slot[dest] = k or "" -- Strings are a good guess for the key type.
125 slot[dest+1] = v -- But better not guess any fixed value type.
126end
127
128
129-- Signatures for base library functions.
130-- Note: Only add functions where result type hints or inlining makes sense.
131flibname, flib, fidx = nil, _G, 65536*1
132fadd("pairs", "..0", "T",
133 function(st, slot, pc, base, narg, nres, idx)
134 -- Table in slot[base+1] is kept (2nd result = 1st arg).
135 -- Fill result slots for the iterator here (TFORLOOP is at the end).
136 guessnext(st, slot, base, base+3)
137 return itercheck(st, slot, pc, base, idx)
138 end)
139
140fadd("ipairs", "..I", "T",
141 function(st, slot, pc, base, narg, nres, idx)
142 -- Table in slot[base+1] is kept (2nd result = 1st arg).
143 -- Fill result slots for the iterator here (TFORLOOP is at the end).
144 local t = slot[base+1]
145 slot[base+3] = 1 -- Integer key.
146 local v
147 if type(t) == "table" then
148 v = rawget(t, 1)
149 if v == nil then v = st.tableval[t] end
150 end
151 slot[base+4] = v
152 return itercheck(st, slot, pc, base, idx)
153 end)
154
155fidx = nil -- Pure result type signatures follow:
156fadd("next", "..", "T.?",
157 function(st, slot, pc, base, narg, nres)
158 guessnext(st, slot, base, base)
159 end)
160fadd("type", "S", ".")
161fadd("getmetatable", "T", ".")
162fadd("setmetatable", ".", "TT?", copyfirst)
163fadd("rawequal", "B", "..")
164fadd("rawget", ".", "T.",
165 function(st, slot, pc, base, narg, nres)
166 local t = slot[base+1]
167 slot[base] = type(t) == "table" and rawget(t, slot[base+2]) or ""
168 end)
169fadd("rawset", ".", "T..", copyfirst)
170fadd("assert", "*", "..*",
171 function(st, slot, pc, base, narg, nres)
172 for i=1,nres do slot[base+i-1] = i <= narg and slot[base+i] or nil end
173 end)
174fadd("tonumber", "I", ".I?")
175fadd("tostring", "S", ".")
176fadd("require", "T", "S")
177
178-- Signatures for coroutine library functions.
179flibname, flib, fidx = "coroutine", coroutine, 65536*2
180if flib then
181 fadd("yield", "*", ".*")
182 fadd("resume", "*", "R.*",
183 function(st, slot, pc, base, narg, nres)
184 slot[base] = true
185 for i=1,nres-1 do slot[base+i] = nil end -- No guess.
186 end)
187
188 fidx = nil -- Pure result type signatures follow:
189 fadd("wrap", "C", "F")
190end
191
192-- Signatures for string library functions.
193flibname, flib, fidx = "string", string, 65536*3
194if flib then
195 fadd("len", "I", "S")
196 fadd("sub", "S", "SII?")
197 fadd("char", "S", "I*")
198
199 fidx = nil -- Pure result type signatures follow:
200 fadd("byte", "I", "S",
201 function(st, slot, pc, base, narg, nres)
202 for i=0,nres-1 do slot[base+i] = 1 end -- Set all result hints.
203 end)
204 fadd("rep", "S", "SI")
205 fadd("reverse", "S", "S")
206 fadd("upper", "S", "S")
207 fadd("lower", "S", "S")
208
209 fadd("format", "S", "S.*")
210 fadd("find", "*", "SSI?.?",
211 function(st, slot, pc, base, narg, nres)
212 slot[base] = 1
213 slot[base+1] = 1
214 for i=2,nres-1 do slot[base+i] = "" end -- Hints for matches.
215 end)
216 fadd("match", "*", "SSI?",
217 function(st, slot, pc, base, narg, nres)
218 for i=0,nres-1 do slot[base+i] = "" end -- Hints for matches.
219 end)
220 fadd("gsub", "SI", "SSGI?")
221 fadd("gmatch", "C00", "SS",
222 function(st, slot, pc, base, narg, nres)
223 -- Fill result slots for gmatch_iter here (TFORLOOP is at the end).
224 for i=base+3,st.stats.stackslots-1 do slot[i] = "" end
225 end)
226 -- The gmatch iterator itself is never inlined. No point in adding it.
227end
228
229-- Signatures for table library functions.
230flibname, flib, fidx = "table", table, 65536*4
231if flib then
232 fadd("insert", "", "TI?.")
233 fadd("remove", ".", "T",
234 function(st, slot, pc, base, narg, nres)
235 if nres >= 1 then
236 local t = slot[base+1]
237 slot[base] = type(t) == "table" and rawget(t, 1) or ""
238 end
239 end)
240 fadd("getn", "I", "T")
241
242 fidx = nil -- Pure result type signatures follow:
243 fadd("concat", "S", "TS?I?I?")
244end
245
246-- Signatures for math library functions.
247flibname, flib, fidx = "math", math, 65536*5
248if flib then
249 -- 1 arg, 1 result.
250 fadd("log", "N", "N")
251 fadd("log10", "N", "N")
252 fadd("exp", "N", "N")
253 fadd("sinh", "N", "N")
254 fadd("cosh", "N", "N")
255 fadd("tanh", "N", "N")
256 fadd("asin", "N", "N")
257 fadd("acos", "N", "N")
258 fadd("atan", "N", "N")
259 fadd("sin", "N", "N")
260 fadd("cos", "N", "N")
261 fadd("tan", "N", "N")
262 fadd("ceil", "I", "N")
263 fadd("floor", "I", "N")
264 fadd("abs", ".", "N", copyfirst)
265 fadd("sqrt", "N", "N")
266 -- 2 args, 1 result.
267 -- math.fmod is aliased to math.mod for compatibility.
268 fadd("fmod", ".", "NN",
269 function(st, slot, pc, base, narg, nres)
270 slot[base] = slot[base+2] or 1 -- Copy integer or number hint.
271 end)
272 fadd("atan2", "N", "NN")
273
274 fidx = nil -- Pure result type signatures follow:
275 -- 1-n args, 1 result.
276 fadd("min", ".", "NN*", copyfirst) -- Really depends on all args.
277 fadd("max", ".", "NN*", copyfirst) -- Really depends on all args.
278 -- 1 arg, 1 result.
279 fadd("deg", "N", "N")
280 fadd("rad", "N", "N")
281 -- 1 arg, 2 results.
282 fadd("modf", "IN", "N")
283 fadd("frexp", "NI", "N")
284 -- 2 args, 1 result.
285 fadd("pow", "N", "NN")
286 fadd("ldexp", ".", "NI", copyfirst)
287 -- 1 arg, 0 results.
288 fadd("randomseed", "", "I")
289 -- 0-2 args, 1 result.
290 fadd("random", "N", "I?I?",
291 function(st, slot, pc, base, narg, nres)
292 if narg > 0 then slot[base] = 1 end
293 end)
294end
295
296-- Signatures for I/O library functions.
297-- Not inlined anytime soon. Used for result types only.
298flibname, flib, fidx = "io", io, nil
299if flib then
300 fadd("lines", "C00S", "S?")
301 fadd("read", "S", "") -- Simplified (a lot).
302 -- Adding io methods doesn't work, because we don't deal with userdata (yet).
303end
304
305
306-- Type names to argument type shorthands.
307-- TODO: make the matches more exact? Need to differentiate nil/unknown.
308local map_argtype = {
309 ["nil"] = "0", boolean = "b", number = "n", string = "s",
310 table = "t", ["function"] = "f", userdata = "u", thread = "r",
311}
312
313-- Complex argument match patterns to regexp fragments.
314local map_argmatch = {
315 B = "[b0]", S = "[s0]", T = "[t0]", F = "[f0]", U = "[u0]", R = "[r0]",
316 N = "[n0]", I = "[n0]", -- Number/int args are the same for now.
317 G = "[stf0]", -- For string.gsub.
318}
319
320-- Result type shorthands to sample types.
321local map_restype = {
322 -- ["0"] = nil,
323 B = true, S = "", T = {},
324 N = 0.5, I = 1,
325 L = function() end, C = collectgarbage, -- Pretty sure this is never inlined.
326}
327
328-- Create argument match regexp and cache it.
329local function getargmatch(sign)
330 local argmatch = "^"..gsub(sign.args, ".", map_argmatch).."0*$"
331 sign.argmatch = argmatch
332 return argmatch
333end
334
335-- Set INLINE hints and result types for known C functions.
336local function inlinehint(sign, st, slot, pc, base, narg, nres)
337 local idx = sign.idx
338 if idx then
339 if narg ~= -1 then
340 local argpat = ""
341 for i=1,narg do argpat = argpat..map_argtype[type(slot[base+i])] end
342 if not match(argpat, sign.argmatch or getargmatch(sign)) then
343 idx = nil
344 end
345 end
346 end
347
348 local results = sign.results
349 if results ~= "*" and nres ~= -1 then
350 if nres > #results then idx = nil end
351 for i=1,#results do
352 local c = sub(results, i, i)
353 if c ~= "." then slot[base+i-1] = map_restype[c] end
354 end
355 end
356
357 local handler = sign.handler
358 if handler and handler(st, slot, pc, base, narg, nres, idx) then idx = nil end
359
360 if idx then st[pc+hints.INLINE] = idx end
361end
362
363-- Set call hints and result types during forward propagation.
364local function fwdcallhint(st, slot, pc, base, narg, nres)
365 local f = slot[base]
366 st[pc+hints.TYPE] = f
367 if type(f) == "function" then
368 local sign = map_sign[f]
369 if sign then
370 inlinehint(sign, st, slot, pc, base, narg, nres)
371 return
372 end
373 if f == st.func and not st.stats.isvararg and
374 (narg == -1 or narg == st.stats.params) then
375 st[pc+hints.INLINE] = 0 -- Recursive call.
376 end
377 end
378 -- Clear result types for unknown functions.
379 for i=base,base+nres-1 do slot[i] = nil end
380end
381
382
383-- Attach call hinter to optimizer.
384local function start_()
385 local jopt = require "jit.opt"
386 jopt.attach_callhint(fwdcallhint)
387 -- Note that just loading the optimizer does not start it, yet.
388end
389
390
391-- Public module functions.
392module(...)
393
394-- TODO: Public API to add signatures. Alas, the API is still in flux.
395getname = getname_
396start = start_
397
diff --git a/libraries/LuaJIT-1.1.7/jit/trace.lua b/libraries/LuaJIT-1.1.7/jit/trace.lua
deleted file mode 100644
index 42367c6..0000000
--- a/libraries/LuaJIT-1.1.7/jit/trace.lua
+++ /dev/null
@@ -1,111 +0,0 @@
1----------------------------------------------------------------------------
2-- LuaJIT compiler tracing module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- Activate this module to trace the progress of the JIT compiler.
8--
9-- Try: luajit -j trace -e 'print "foo"'
10-- luajit -j trace=foo.trace foo.lua
11--
12-- Default output is to stderr. To redirect output to a file,
13-- pass a filename as an argument or set the environment variable
14-- "LUAJIT_TRACEFILE".
15-- Note: the file is overwritten each time you run luajit.
16------------------------------------------------------------------------------
17
18-- Priority for compiler pipeline. Must run after backend (negative)
19-- and should be odd to catch compiler errors, too.
20local PRIORITY = -99
21
22-- Cache some library functions and objects.
23local jit = require("jit")
24assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
25local jutil = require("jit.util")
26local type, tostring, sub, format = type, tostring, string.sub, string.format
27local getinfo, justats = debug.getinfo, jutil.stats
28local stdout, stderr = io.stdout, io.stderr
29
30-- Turn compilation off for the whole module. LuaJIT would do that anyway.
31jit.off(true, true)
32
33-- Active flag and output file handle.
34local active, out
35
36-- Generate range string from table: pc[-pc] [,...]
37local function rangestring(t)
38 local s = ""
39 for i,range in ipairs(t) do
40 if i ~= 1 then s = s.."," end
41 local pc = range % 65536
42 range = (range - pc) / 65536
43 s = s..pc
44 if range ~= 0 then s = s..(-(pc+range)) end
45 end
46 return s
47end
48
49-- Trace handler for compiler pipeline.
50local function h_trace(st, status)
51 local o = out or stderr
52 local func = st.func
53 if type(func) ~= "function" then return end
54 local info = getinfo(func, "S")
55 local src, line = info.source, info.linedefined or 0
56 if src then
57 if sub(src, 1, 1) == "@" or sub(src, 1, 2) == "=(" then
58 src = sub(src, 2)
59 else
60 src = "**"..string.gsub(sub(src, 1, 40), "%c", " ").."**"
61 end
62 else
63 src = "?"
64 end
65 local aux = st.deopt and " DEOPT="..rangestring(st.deopt) or ""
66 if status == nil then
67 local stats = justats(func)
68 if not stats then return end
69 o:write(format("[LuaJIT: OK %4d %6d %s:%d%s]\n",
70 stats.bytecodes, stats.mcodesize or -1, src, line, aux))
71 return
72 else
73 local stname = jit.util.status[status] or status
74 local pc, err = st.dasm_pc, st.dasm_err
75 if type(pc) == "number" and type(err) == "number" then
76 local op = jutil.bytecode(func, pc) or "END"
77 o:write(format("[LuaJIT: %s %s@%d %08x %s:%d%s]\n",
78 stname, op, pc, err, src, line, aux))
79 else
80 o:write(format("[LuaJIT: %s %s:%d%s]\n", stname, src, line, aux))
81 end
82 end
83end
84
85-- Detach trace handler from compiler pipeline.
86local function traceoff()
87 if active then
88 active = false
89 jit.attach(h_trace)
90 if out and out ~= stdout then out:close() end
91 out = nil
92 end
93end
94
95-- Open the output file and attach trace handler to compiler pipeline.
96local function traceon(filename)
97 if active then traceoff() end
98 local outfile = filename or os.getenv("LUAJIT_TRACEFILE")
99 out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w")))
100 jit.attach(h_trace, PRIORITY)
101 active = true
102end
103
104
105-- Public module functions.
106module(...)
107
108on = traceon
109off = traceoff
110start = traceon -- For -j command line option.
111