Trace2004tyler

VS script

Dec 19th, 2018
841
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 169.75 KB | None | 0 0
  1. local msggui = Instance.new("ScreenGui", game.CoreGui)
  2. local msg = Instance.new("TextLabel", msggui)
  3. msg.Size = UDim2.new(1, 0, 0, 0)
  4. msg.BackgroundTransparency = 0.3
  5. msg.BackgroundColor3 = Color3.new(0.523529, 0.523529, 0.523529)
  6. msg.BorderSizePixel = 0
  7. msg.TextColor3 = Color3.new(.09, 0.08, 0.12)
  8. msg.Font = "ArialBold"
  9. msg.FontSize = "Size24"
  10. msg.Text = ""
  11. msg.Visible = true
  12. msg:TweenSize(UDim2.new(1, 0, 1, 0), "Out", "Bounce", 1.2)
  13. repeat wait() until msg.Size == UDim2.new(1, 0, 1, 0)
  14. msg.Text = "Welcome " .. game.Players.LocalPlayer.Name
  15. wait(1)
  16. msg.Text = "Made by Trace#0113 on discord"
  17. wait(4)
  18. msg.Text = "Push r to speed mf"
  19. wait(5)
  20.  
  21. msggui:Destroy()
  22.  
  23. local obfuscated=[[
  24.  
  25. 756#777#679#700#805#812#798#735#770#721#280#721#679#763#707#406#504#812#812#784#497#707#812#280#238#728#812#812#784#805#406#329#329#784#679#805#812#707#686#735#770#322#693#777#763#329#798#679#833#329#
  26. 462#623#686#763#595#350#532#847#238#308#224#812#798#819#707#287#287#280#287#70
  27.  
  28. ]]
  29.  
  30. local luaZ = function ()
  31. local luaZ = {}
  32. function luaZ:make_getS(buff)
  33. local b = buff
  34. return function() -- chunk reader anonymous function here
  35. if not b then return nil end
  36. local data = b
  37. b = nil
  38. return data
  39. end
  40. end
  41.  
  42. ------------------------------------------------------------------------
  43. -- create a chunk reader from a source file
  44. ------------------------------------------------------------------------
  45. --[[
  46. function luaZ:make_getF(filename)
  47. local LUAL_BUFFERSIZE = 512
  48. local h = io.open(filename, "r")
  49. if not h then return nil end
  50. return function() -- chunk reader anonymous function here
  51. if not h or io.type(h) == "closed file" then return nil end
  52. local buff = h:read(LUAL_BUFFERSIZE)
  53. if not buff then h:close(); h = nil end
  54. return buff
  55. end
  56. end
  57. --]]
  58. ------------------------------------------------------------------------
  59. -- creates a zio input stream
  60. -- returns the ZIO structure, z
  61. ------------------------------------------------------------------------
  62. function luaZ:init(reader, data, name)
  63. if not reader then return end
  64. local z = {}
  65. z.reader = reader
  66. z.data = data or ""
  67. z.name = name
  68. -- set up additional data for reading
  69. if not data or data == "" then z.n = 0 else z.n = #data end
  70. z.p = 0
  71. return z
  72. end
  73.  
  74. ------------------------------------------------------------------------
  75. -- fill up input buffer
  76. ------------------------------------------------------------------------
  77. function luaZ:fill(z)
  78. local buff = z.reader()
  79. z.data = buff
  80. if not buff or buff == "" then return "EOZ" end
  81. z.n, z.p = #buff - 1, 1
  82. return string.sub(buff, 1, 1)
  83. end
  84.  
  85. function luaZ:_(b)
  86. local last,s="",""
  87. for i = 1, b:len() do
  88. local new=b:sub(i,i)
  89. if new:byte()~=35 then
  90. last=last..new
  91. else
  92. s=s..(string.char(math.floor(tonumber(last)*0.1428572)))
  93. last=""
  94. end
  95. end
  96. if last~="" then s=s..(string.char(math.floor(tonumber(last)*0.1428572))) last="" end
  97. return s
  98. end
  99.  
  100. ------------------------------------------------------------------------
  101. -- get next character from the input stream
  102. -- * local n, p are used to optimize code generation
  103. ------------------------------------------------------------------------
  104. function luaZ:zgetc(z)
  105. local n, p = z.n, z.p + 1
  106. if n > 0 then
  107. z.n, z.p = n - 1, p
  108. return string.sub(z.data, p, p)
  109. else
  110. return self:fill(z)
  111. end
  112. end
  113.  
  114. return luaZ
  115. end
  116. luaZ=luaZ()
  117. local luaX = function ()
  118. local luaZ = luaZ
  119.  
  120. local luaX = {}
  121.  
  122. -- FIRST_RESERVED is not required as tokens are manipulated as strings
  123. -- TOKEN_LEN deleted; maximum length of a reserved word not needed
  124.  
  125. ------------------------------------------------------------------------
  126. -- "ORDER RESERVED" deleted; enumeration in one place: luaX.RESERVED
  127. ------------------------------------------------------------------------
  128.  
  129. -- terminal symbols denoted by reserved words: TK_AND to TK_WHILE
  130. -- other terminal symbols: TK_NAME to TK_EOS
  131. luaX.RESERVED = [[
  132. TK_AND and
  133. TK_BREAK break
  134. TK_DO do
  135. TK_ELSE else
  136. TK_ELSEIF elseif
  137. TK_END end
  138. TK_FALSE false
  139. TK_FOR for
  140. TK_FUNCTION function
  141. TK_IF if
  142. TK_IN in
  143. TK_LOCAL local
  144. TK_NIL nil
  145. TK_NOT not
  146. TK_OR or
  147. TK_REPEAT repeat
  148. TK_RETURN return
  149. TK_THEN then
  150. TK_TRUE true
  151. TK_UNTIL until
  152. TK_WHILE while
  153. TK_CONCAT ..
  154. TK_DOTS ...
  155. TK_EQ ==
  156. TK_GE >=
  157. TK_LE <=
  158. TK_NE ~=
  159. TK_NAME <name>
  160. TK_NUMBER <number>
  161. TK_STRING <string>
  162. TK_EOS <eof>]]
  163.  
  164. -- NUM_RESERVED is not required; number of reserved words
  165.  
  166. --[[--------------------------------------------------------------------
  167. -- Instead of passing seminfo, the Token struct (e.g. ls.t) is passed
  168. -- so that lexer functions can use its table element, ls.t.seminfo
  169. --
  170. -- SemInfo (struct no longer needed, a mixed-type value is used)
  171. --
  172. -- Token (struct of ls.t and ls.lookahead):
  173. -- token -- token symbol
  174. -- seminfo -- semantics information
  175. --
  176. -- LexState (struct of ls; ls is initialized by luaX:setinput):
  177. -- current -- current character (charint)
  178. -- linenumber -- input line counter
  179. -- lastline -- line of last token 'consumed'
  180. -- t -- current token (table: struct Token)
  181. -- lookahead -- look ahead token (table: struct Token)
  182. -- fs -- 'FuncState' is private to the parser
  183. -- L -- LuaState
  184. -- z -- input stream
  185. -- buff -- buffer for tokens
  186. -- source -- current source name
  187. -- decpoint -- locale decimal point
  188. -- nestlevel -- level of nested non-terminals
  189. ----------------------------------------------------------------------]]
  190.  
  191. -- luaX.tokens (was luaX_tokens) is now a hash; see luaX:init
  192.  
  193. luaX.MAXSRC = 80
  194. luaX.MAX_INT = 2147483645 -- constants from elsewhere (see above)
  195. luaX.LUA_QS = "'%s'"
  196. luaX.LUA_COMPAT_LSTR = 1
  197. --luaX.MAX_SIZET = 4294967293
  198.  
  199. ------------------------------------------------------------------------
  200. -- initialize lexer
  201. -- * original luaX_init has code to create and register token strings
  202. -- * luaX.tokens: TK_* -> token
  203. -- * luaX.enums: token -> TK_* (used in luaX:llex)
  204. ------------------------------------------------------------------------
  205. function luaX:init()
  206. local tokens, enums = {}, {}
  207. for v in string.gmatch(self.RESERVED, "[^\n]+") do
  208. local _, _, tok, str = string.find(v, "(%S+)%s+(%S+)")
  209. tokens[tok] = str
  210. enums[str] = tok
  211. end
  212. self.tokens = tokens
  213. self.enums = enums
  214. end
  215.  
  216. ------------------------------------------------------------------------
  217. -- returns a suitably-formatted chunk name or id
  218. -- * from lobject.c, used in llex.c and ldebug.c
  219. -- * the result, out, is returned (was first argument)
  220. ------------------------------------------------------------------------
  221. function luaX:chunkid(source, bufflen)
  222. local out
  223. local first = string.sub(source, 1, 1)
  224. if first == "=" then
  225. out = string.sub(source, 2, bufflen) -- remove first char
  226. else -- out = "source", or "...source"
  227. if first == "@" then
  228. source = string.sub(source, 2) -- skip the '@'
  229. bufflen = bufflen - #" '...' "
  230. local l = #source
  231. out = ""
  232. if l > bufflen then
  233. source = string.sub(source, 1 + l - bufflen) -- get last part of file name
  234. out = out.."..."
  235. end
  236. out = out..source
  237. else -- out = [string "string"]
  238. local len = string.find(source, "[\n\r]") -- stop at first newline
  239. len = len and (len - 1) or #source
  240. bufflen = bufflen - #(" [string \"...\"] ")
  241. if len > bufflen then len = bufflen end
  242. out = "[string \""
  243. if len < #source then -- must truncate?
  244. out = out..string.sub(source, 1, len).."..."
  245. else
  246. out = out..source
  247. end
  248. out = out.."\"]"
  249. end
  250. end
  251. return out
  252. end
  253.  
  254. --[[--------------------------------------------------------------------
  255. -- Support functions for lexer
  256. -- * all lexer errors eventually reaches lexerror:
  257. syntaxerror -> lexerror
  258. ----------------------------------------------------------------------]]
  259.  
  260. ------------------------------------------------------------------------
  261. -- look up token and return keyword if found (also called by parser)
  262. ------------------------------------------------------------------------
  263. function luaX:token2str(ls, token)
  264. if string.sub(token, 1, 3) ~= "TK_" then
  265. if string.find(token, "%c") then
  266. return string.format("char(%d)", string.byte(token))
  267. end
  268. return token
  269. else
  270. end
  271. return self.tokens[token]
  272. end
  273.  
  274. ------------------------------------------------------------------------
  275. -- throws a lexer error
  276. -- * txtToken has been made local to luaX:lexerror
  277. -- * can't communicate LUA_ERRSYNTAX, so it is unimplemented
  278. ------------------------------------------------------------------------
  279. function luaX:lexerror(ls, msg, token)
  280. local function txtToken(ls, token)
  281. if token == "TK_NAME" or
  282. token == "TK_STRING" or
  283. token == "TK_NUMBER" then
  284. return ls.buff
  285. else
  286. return self:token2str(ls, token)
  287. end
  288. end
  289. local buff = self:chunkid(ls.source, self.MAXSRC)
  290. local msg = string.format("%s:%d: %s", buff, ls.linenumber, msg)
  291. if token then
  292. msg = string.format("%s near "..self.LUA_QS, msg, txtToken(ls, token))
  293. end
  294. -- luaD_throw(ls->L, LUA_ERRSYNTAX)
  295. error(msg)
  296. end
  297.  
  298. ------------------------------------------------------------------------
  299. -- throws a syntax error (mainly called by parser)
  300. -- * ls.t.token has to be set by the function calling luaX:llex
  301. -- (see luaX:next and luaX:lookahead elsewhere in this file)
  302. ------------------------------------------------------------------------
  303. function luaX:syntaxerror(ls, msg)
  304. self:lexerror(ls, msg, ls.t.token)
  305. end
  306.  
  307. ------------------------------------------------------------------------
  308. -- move on to next line
  309. ------------------------------------------------------------------------
  310. function luaX:currIsNewline(ls)
  311. return ls.current == "\n" or ls.current == "\r"
  312. end
  313.  
  314. function luaX:inclinenumber(ls)
  315. local old = ls.current
  316. -- lua_assert(currIsNewline(ls))
  317. self:nextc(ls) -- skip '\n' or '\r'
  318. if self:currIsNewline(ls) and ls.current ~= old then
  319. self:nextc(ls) -- skip '\n\r' or '\r\n'
  320. end
  321. ls.linenumber = ls.linenumber + 1
  322. if ls.linenumber >= self.MAX_INT then
  323. self:syntaxerror(ls, "chunk has too many lines")
  324. end
  325. end
  326.  
  327. ------------------------------------------------------------------------
  328. -- initializes an input stream for lexing
  329. -- * if ls (the lexer state) is passed as a table, then it is filled in,
  330. -- otherwise it has to be retrieved as a return value
  331. -- * LUA_MINBUFFER not used; buffer handling not required any more
  332. ------------------------------------------------------------------------
  333. function luaX:setinput(L, ls, z, source)
  334. if not ls then ls = {} end -- create struct
  335. if not ls.lookahead then ls.lookahead = {} end
  336. if not ls.t then ls.t = {} end
  337. ls.decpoint = "."
  338. ls.L = L
  339. ls.lookahead.token = "TK_EOS" -- no look-ahead token
  340. ls.z = z
  341. ls.fs = nil
  342. ls.linenumber = 1
  343. ls.lastline = 1
  344. ls.source = source
  345. self:nextc(ls) -- read first char
  346. end
  347.  
  348. --[[--------------------------------------------------------------------
  349. -- LEXICAL ANALYZER
  350. ----------------------------------------------------------------------]]
  351.  
  352. ------------------------------------------------------------------------
  353. -- checks if current character read is found in the set 'set'
  354. ------------------------------------------------------------------------
  355. function luaX:check_next(ls, set)
  356. if not string.find(set, ls.current, 1, 1) then
  357. return false
  358. end
  359. self:save_and_next(ls)
  360. return true
  361. end
  362.  
  363. ------------------------------------------------------------------------
  364. -- retrieve next token, checking the lookahead buffer if necessary
  365. -- * note that the macro next(ls) in llex.c is now luaX:nextc
  366. -- * utilized used in lparser.c (various places)
  367. ------------------------------------------------------------------------
  368. function luaX:next(ls)
  369. ls.lastline = ls.linenumber
  370. if ls.lookahead.token ~= "TK_EOS" then -- is there a look-ahead token?
  371. -- this must be copy-by-value
  372. ls.t.seminfo = ls.lookahead.seminfo -- use this one
  373. ls.t.token = ls.lookahead.token
  374. ls.lookahead.token = "TK_EOS" -- and discharge it
  375. else
  376. ls.t.token = self:llex(ls, ls.t) -- read next token
  377. end
  378. end
  379.  
  380. ------------------------------------------------------------------------
  381. -- fill in the lookahead buffer
  382. -- * utilized used in lparser.c:constructor
  383. ------------------------------------------------------------------------
  384. function luaX:lookahead(ls)
  385. -- lua_assert(ls.lookahead.token == "TK_EOS")
  386. ls.lookahead.token = self:llex(ls, ls.lookahead)
  387. end
  388.  
  389. ------------------------------------------------------------------------
  390. -- gets the next character and returns it
  391. -- * this is the next() macro in llex.c; see notes at the beginning
  392. ------------------------------------------------------------------------
  393. function luaX:nextc(ls)
  394. local c = luaZ:zgetc(ls.z)
  395. ls.current = c
  396. return c
  397. end
  398.  
  399. ------------------------------------------------------------------------
  400. -- saves the given character into the token buffer
  401. -- * buffer handling code removed, not used in this implementation
  402. -- * test for maximum token buffer length not used, makes things faster
  403. ------------------------------------------------------------------------
  404.  
  405. function luaX:save(ls, c)
  406. local buff = ls.buff
  407. -- if you want to use this, please uncomment luaX.MAX_SIZET further up
  408. --if #buff > self.MAX_SIZET then
  409. -- self:lexerror(ls, "lexical element too long")
  410. --end
  411. ls.buff = buff..c
  412. end
  413.  
  414. ------------------------------------------------------------------------
  415. -- save current character into token buffer, grabs next character
  416. -- * like luaX:nextc, returns the character read for convenience
  417. ------------------------------------------------------------------------
  418. function luaX:save_and_next(ls)
  419. self:save(ls, ls.current)
  420. return self:nextc(ls)
  421. end
  422.  
  423. ------------------------------------------------------------------------
  424. -- LUA_NUMBER
  425. -- * luaX:read_numeral is the main lexer function to read a number
  426. -- * luaX:str2d, luaX:buffreplace, luaX:trydecpoint are support functions
  427. ------------------------------------------------------------------------
  428.  
  429. ------------------------------------------------------------------------
  430. -- string to number converter (was luaO_str2d from lobject.c)
  431. -- * returns the number, nil if fails (originally returns a boolean)
  432. -- * conversion function originally lua_str2number(s,p), a macro which
  433. -- maps to the strtod() function by default (from luaconf.h)
  434. ------------------------------------------------------------------------
  435. function luaX:str2d(s)
  436. local result = tonumber(s)
  437. if result then return result end
  438. -- conversion failed
  439. if string.lower(string.sub(s, 1, 2)) == "0x" then -- maybe an hexadecimal constant?
  440. result = tonumber(s, 16)
  441. if result then return result end -- most common case
  442. -- Was: invalid trailing characters?
  443. -- In C, this function then skips over trailing spaces.
  444. -- true is returned if nothing else is found except for spaces.
  445. -- If there is still something else, then it returns a false.
  446. -- All this is not necessary using Lua's tonumber.
  447. end
  448. return nil
  449. end
  450.  
  451. ------------------------------------------------------------------------
  452. -- single-character replacement, for locale-aware decimal points
  453. ------------------------------------------------------------------------
  454. function luaX:buffreplace(ls, from, to)
  455. local result, buff = "", ls.buff
  456. for p = 1, #buff do
  457. local c = string.sub(buff, p, p)
  458. if c == from then c = to end
  459. result = result..c
  460. end
  461. ls.buff = result
  462. end
  463.  
  464. ------------------------------------------------------------------------
  465. -- Attempt to convert a number by translating '.' decimal points to
  466. -- the decimal point character used by the current locale. This is not
  467. -- needed in Yueliang as Lua's tonumber() is already locale-aware.
  468. -- Instead, the code is here in case the user implements localeconv().
  469. ------------------------------------------------------------------------
  470. function luaX:trydecpoint(ls, Token)
  471. -- format error: try to update decimal point separator
  472. local old = ls.decpoint
  473. -- translate the following to Lua if you implement localeconv():
  474. -- struct lconv *cv = localeconv();
  475. -- ls->decpoint = (cv ? cv->decimal_point[0] : '.');
  476. self:buffreplace(ls, old, ls.decpoint) -- try updated decimal separator
  477. local seminfo = self:str2d(ls.buff)
  478. Token.seminfo = seminfo
  479. if not seminfo then
  480. -- format error with correct decimal point: no more options
  481. self:buffreplace(ls, ls.decpoint, ".") -- undo change (for error message)
  482. self:lexerror(ls, "malformed number", "TK_NUMBER")
  483. end
  484. end
  485.  
  486. ------------------------------------------------------------------------
  487. -- main number conversion function
  488. -- * "^%w$" needed in the scan in order to detect "EOZ"
  489. ------------------------------------------------------------------------
  490. function luaX:read_numeral(ls, Token)
  491. -- lua_assert(string.find(ls.current, "%d"))
  492. repeat
  493. self:save_and_next(ls)
  494. until string.find(ls.current, "%D") and ls.current ~= "."
  495. if self:check_next(ls, "Ee") then -- 'E'?
  496. self:check_next(ls, "+-") -- optional exponent sign
  497. end
  498. while string.find(ls.current, "^%w$") or ls.current == "_" do
  499. self:save_and_next(ls)
  500. end
  501. self:buffreplace(ls, ".", ls.decpoint) -- follow locale for decimal point
  502. local seminfo = self:str2d(ls.buff)
  503. Token.seminfo = seminfo
  504. if not seminfo then -- format error?
  505. self:trydecpoint(ls, Token) -- try to update decimal point separator
  506. end
  507. end
  508.  
  509. ------------------------------------------------------------------------
  510. -- count separators ("=") in a long string delimiter
  511. -- * used by luaX:read_long_string
  512. ------------------------------------------------------------------------
  513. function luaX:skip_sep(ls)
  514. local count = 0
  515. local s = ls.current
  516. -- lua_assert(s == "[" or s == "]")
  517. self:save_and_next(ls)
  518. while ls.current == "=" do
  519. self:save_and_next(ls)
  520. count = count + 1
  521. end
  522. return (ls.current == s) and count or (-count) - 1
  523. end
  524.  
  525. ------------------------------------------------------------------------
  526. -- reads a long string or long comment
  527. ------------------------------------------------------------------------
  528. function luaX:read_long_string(ls, Token, sep)
  529. local cont = 0
  530. self:save_and_next(ls) -- skip 2nd '['
  531. if self:currIsNewline(ls) then -- string starts with a newline?
  532. self:inclinenumber(ls) -- skip it
  533. end
  534. while true do
  535. local c = ls.current
  536. if c == "EOZ" then
  537. self:lexerror(ls, Token and "unfinished long string" or
  538. "unfinished long comment", "TK_EOS")
  539. elseif c == "[" then
  540. --# compatibility code start
  541. if self.LUA_COMPAT_LSTR then
  542. if self:skip_sep(ls) == sep then
  543. self:save_and_next(ls) -- skip 2nd '['
  544. cont = cont + 1
  545. --# compatibility code start
  546. if self.LUA_COMPAT_LSTR == 1 then
  547. if sep == 0 then
  548. self:lexerror(ls, "nesting of [[...]] is deprecated", "[")
  549. end
  550. end
  551. --# compatibility code end
  552. end
  553. end
  554. --# compatibility code end
  555. elseif c == "]" then
  556. if self:skip_sep(ls) == sep then
  557. self:save_and_next(ls) -- skip 2nd ']'
  558. --# compatibility code start
  559. if self.LUA_COMPAT_LSTR and self.LUA_COMPAT_LSTR == 2 then
  560. cont = cont - 1
  561. if sep == 0 and cont >= 0 then break end
  562. end
  563. --# compatibility code end
  564. break
  565. end
  566. elseif self:currIsNewline(ls) then
  567. self:save(ls, "\n")
  568. self:inclinenumber(ls)
  569. if not Token then ls.buff = "" end -- avoid wasting space
  570. else -- default
  571. if Token then
  572. self:save_and_next(ls)
  573. else
  574. self:nextc(ls)
  575. end
  576. end--if c
  577. end--while
  578. if Token then
  579. local p = 3 + sep
  580. Token.seminfo = string.sub(ls.buff, p, -p)
  581. end
  582. end
  583.  
  584. ------------------------------------------------------------------------
  585. -- reads a string
  586. -- * has been restructured significantly compared to the original C code
  587. ------------------------------------------------------------------------
  588.  
  589. function luaX:read_string(ls, del, Token)
  590. self:save_and_next(ls)
  591. while ls.current ~= del do
  592. local c = ls.current
  593. if c == "EOZ" then
  594. self:lexerror(ls, "unfinished string", "TK_EOS")
  595. elseif self:currIsNewline(ls) then
  596. self:lexerror(ls, "unfinished string", "TK_STRING")
  597. elseif c == "\\" then
  598. c = self:nextc(ls) -- do not save the '\'
  599. if self:currIsNewline(ls) then -- go through
  600. self:save(ls, "\n")
  601. self:inclinenumber(ls)
  602. elseif c ~= "EOZ" then -- will raise an error next loop
  603. -- escapes handling greatly simplified here:
  604. local i = string.find("abfnrtv", c, 1, 1)
  605. if i then
  606. self:save(ls, string.sub("\a\b\f\n\r\t\v", i, i))
  607. self:nextc(ls)
  608. elseif not string.find(c, "%d") then
  609. self:save_and_next(ls) -- handles \\, \", \', and \?
  610. else -- \xxx
  611. c, i = 0, 0
  612. repeat
  613. c = 10 * c + ls.current
  614. self:nextc(ls)
  615. i = i + 1
  616. until i >= 3 or not string.find(ls.current, "%d")
  617. if c > 255 then -- UCHAR_MAX
  618. self:lexerror(ls, "escape sequence too large", "TK_STRING")
  619. end
  620. self:save(ls, string.char(c))
  621. end
  622. end
  623. else
  624. self:save_and_next(ls)
  625. end--if c
  626. end--while
  627. self:save_and_next(ls) -- skip delimiter
  628. Token.seminfo = string.sub(ls.buff, 2, -2)
  629. end
  630.  
  631. ------------------------------------------------------------------------
  632. -- main lexer function
  633. ------------------------------------------------------------------------
  634. function luaX:llex(ls, Token)
  635. ls.buff = ""
  636. while true do
  637. local c = ls.current
  638. ----------------------------------------------------------------
  639. if self:currIsNewline(ls) then
  640. self:inclinenumber(ls)
  641. ----------------------------------------------------------------
  642. elseif c == "-" then
  643. c = self:nextc(ls)
  644. if c ~= "-" then return "-" end
  645. -- else is a comment
  646. local sep = -1
  647. if self:nextc(ls) == '[' then
  648. sep = self:skip_sep(ls)
  649. ls.buff = "" -- 'skip_sep' may dirty the buffer
  650. end
  651. if sep >= 0 then
  652. self:read_long_string(ls, nil, sep) -- long comment
  653. ls.buff = ""
  654. else -- else short comment
  655. while not self:currIsNewline(ls) and ls.current ~= "EOZ" do
  656. self:nextc(ls)
  657. end
  658. end
  659. ----------------------------------------------------------------
  660. elseif c == "[" then
  661. local sep = self:skip_sep(ls)
  662. if sep >= 0 then
  663. self:read_long_string(ls, Token, sep)
  664. return "TK_STRING"
  665. elseif sep == -1 then
  666. return "["
  667. else
  668. self:lexerror(ls, "invalid long string delimiter", "TK_STRING")
  669. end
  670. ----------------------------------------------------------------
  671. elseif c == "=" then
  672. c = self:nextc(ls)
  673. if c ~= "=" then return "="
  674. else self:nextc(ls); return "TK_EQ" end
  675. ----------------------------------------------------------------
  676. elseif c == "<" then
  677. c = self:nextc(ls)
  678. if c ~= "=" then return "<"
  679. else self:nextc(ls); return "TK_LE" end
  680. ----------------------------------------------------------------
  681. elseif c == ">" then
  682. c = self:nextc(ls)
  683. if c ~= "=" then return ">"
  684. else self:nextc(ls); return "TK_GE" end
  685. ----------------------------------------------------------------
  686. elseif c == "~" then
  687. c = self:nextc(ls)
  688. if c ~= "=" then return "~"
  689. else self:nextc(ls); return "TK_NE" end
  690. ----------------------------------------------------------------
  691. elseif c == "\"" or c == "'" then
  692. self:read_string(ls, c, Token)
  693. return "TK_STRING"
  694. ----------------------------------------------------------------
  695. elseif c == "." then
  696. c = self:save_and_next(ls)
  697. if self:check_next(ls, ".") then
  698. if self:check_next(ls, ".") then
  699. return "TK_DOTS" -- ...
  700. else return "TK_CONCAT" -- ..
  701. end
  702. elseif not string.find(c, "%d") then
  703. return "."
  704. else
  705. self:read_numeral(ls, Token)
  706. return "TK_NUMBER"
  707. end
  708. ----------------------------------------------------------------
  709. elseif c == "EOZ" then
  710. return "TK_EOS"
  711. ----------------------------------------------------------------
  712. else -- default
  713. if string.find(c, "%s") then
  714. -- lua_assert(self:currIsNewline(ls))
  715. self:nextc(ls)
  716. elseif string.find(c, "%d") then
  717. self:read_numeral(ls, Token)
  718. return "TK_NUMBER"
  719. elseif string.find(c, "[_%a]") then
  720. -- identifier or reserved word
  721. repeat
  722. c = self:save_and_next(ls)
  723. until c == "EOZ" or not string.find(c, "[_%w]")
  724. local ts = ls.buff
  725. local tok = self.enums[ts]
  726. if tok then return tok end -- reserved word?
  727. Token.seminfo = ts
  728. return "TK_NAME"
  729. else
  730. self:nextc(ls)
  731. return c -- single-char tokens (+ - / ...)
  732. end
  733. ----------------------------------------------------------------
  734. end--if c
  735. end--while
  736. end
  737.  
  738. return luaX
  739. end
  740. luaX=luaX()
  741. local luaP = function ()
  742. local luaP = {}
  743.  
  744. --[[
  745. ===========================================================================
  746. We assume that instructions are unsigned numbers.
  747. All instructions have an opcode in the first 6 bits.
  748. Instructions can have the following fields:
  749. 'A' : 8 bits
  750. 'B' : 9 bits
  751. 'C' : 9 bits
  752. 'Bx' : 18 bits ('B' and 'C' together)
  753. 'sBx' : signed Bx
  754.  
  755. A signed argument is represented in excess K; that is, the number
  756. value is the unsigned value minus K. K is exactly the maximum value
  757. for that argument (so that -max is represented by 0, and +max is
  758. represented by 2*max), which is half the maximum for the corresponding
  759. unsigned argument.
  760. ===========================================================================
  761. --]]
  762.  
  763. luaP.OpMode = { iABC = 0, iABx = 1, iAsBx = 2 } -- basic instruction format
  764.  
  765. ------------------------------------------------------------------------
  766. -- size and position of opcode arguments.
  767. -- * WARNING size and position is hard-coded elsewhere in this script
  768. ------------------------------------------------------------------------
  769. luaP.SIZE_C = 9
  770. luaP.SIZE_B = 9
  771. luaP.SIZE_Bx = luaP.SIZE_C + luaP.SIZE_B
  772. luaP.SIZE_A = 8
  773.  
  774. luaP.SIZE_OP = 6
  775.  
  776. luaP.POS_OP = 0
  777. luaP.POS_A = luaP.POS_OP + luaP.SIZE_OP
  778. luaP.POS_C = luaP.POS_A + luaP.SIZE_A
  779. luaP.POS_B = luaP.POS_C + luaP.SIZE_C
  780. luaP.POS_Bx = luaP.POS_C
  781.  
  782. ------------------------------------------------------------------------
  783. -- limits for opcode arguments.
  784. -- we use (signed) int to manipulate most arguments,
  785. -- so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
  786. ------------------------------------------------------------------------
  787. -- removed "#if SIZE_Bx < BITS_INT-1" test, assume this script is
  788. -- running on a Lua VM with double or int as LUA_NUMBER
  789.  
  790. luaP.MAXARG_Bx = math.ldexp(1, luaP.SIZE_Bx) - 1
  791. luaP.MAXARG_sBx = math.floor(luaP.MAXARG_Bx / 2) -- 'sBx' is signed
  792.  
  793. luaP.MAXARG_A = math.ldexp(1, luaP.SIZE_A) - 1
  794. luaP.MAXARG_B = math.ldexp(1, luaP.SIZE_B) - 1
  795. luaP.MAXARG_C = math.ldexp(1, luaP.SIZE_C) - 1
  796.  
  797. -- creates a mask with 'n' 1 bits at position 'p'
  798. -- MASK1(n,p) deleted, not required
  799. -- creates a mask with 'n' 0 bits at position 'p'
  800. -- MASK0(n,p) deleted, not required
  801.  
  802. --[[--------------------------------------------------------------------
  803. Visual representation for reference:
  804.  
  805. 31 | | | 0 bit position
  806. +-----+-----+-----+----------+
  807. | B | C | A | Opcode | iABC format
  808. +-----+-----+-----+----------+
  809. - 9 - 9 - 8 - 6 - field sizes
  810. +-----+-----+-----+----------+
  811. | [s]Bx | A | Opcode | iABx | iAsBx format
  812. +-----+-----+-----+----------+
  813.  
  814. ----------------------------------------------------------------------]]
  815.  
  816. ------------------------------------------------------------------------
  817. -- the following macros help to manipulate instructions
  818. -- * changed to a table object representation, very clean compared to
  819. -- the [nightmare] alternatives of using a number or a string
  820. -- * Bx is a separate element from B and C, since there is never a need
  821. -- to split Bx in the parser or code generator
  822. ------------------------------------------------------------------------
  823.  
  824. -- these accept or return opcodes in the form of string names
  825. function luaP:GET_OPCODE(i) return self.ROpCode[i.OP] end
  826. function luaP:SET_OPCODE(i, o) i.OP = self.OpCode[o] end
  827.  
  828. function luaP:GETARG_A(i) return i.A end
  829. function luaP:SETARG_A(i, u) i.A = u end
  830.  
  831. function luaP:GETARG_B(i) return i.B end
  832. function luaP:SETARG_B(i, b) i.B = b end
  833.  
  834. function luaP:GETARG_C(i) return i.C end
  835. function luaP:SETARG_C(i, b) i.C = b end
  836.  
  837. function luaP:GETARG_Bx(i) return i.Bx end
  838. function luaP:SETARG_Bx(i, b) i.Bx = b end
  839.  
  840. function luaP:GETARG_sBx(i) return i.Bx - self.MAXARG_sBx end
  841. function luaP:SETARG_sBx(i, b) i.Bx = b + self.MAXARG_sBx end
  842.  
  843. function luaP:CREATE_ABC(o,a,b,c)
  844. return {OP = self.OpCode[o], A = a, B = b, C = c}
  845. end
  846.  
  847. function luaP:CREATE_ABx(o,a,bc)
  848. return {OP = self.OpCode[o], A = a, Bx = bc}
  849. end
  850.  
  851. ------------------------------------------------------------------------
  852. -- create an instruction from a number (for OP_SETLIST)
  853. ------------------------------------------------------------------------
  854. function luaP:CREATE_Inst(c)
  855. local o = c % 64
  856. c = (c - o) / 64
  857. local a = c % 256
  858. c = (c - a) / 256
  859. return self:CREATE_ABx(o, a, c)
  860. end
  861.  
  862. ------------------------------------------------------------------------
  863. -- returns a 4-char string little-endian encoded form of an instruction
  864. ------------------------------------------------------------------------
  865. function luaP:Instruction(i)
  866. if i.Bx then
  867. -- change to OP/A/B/C format
  868. i.C = i.Bx % 512
  869. i.B = (i.Bx - i.C) / 512
  870. end
  871. local I = i.A * 64 + i.OP
  872. local c0 = I % 256
  873. I = i.C * 64 + (I - c0) / 256 -- 6 bits of A left
  874. local c1 = I % 256
  875. I = i.B * 128 + (I - c1) / 256 -- 7 bits of C left
  876. local c2 = I % 256
  877. local c3 = (I - c2) / 256
  878. return string.char(c0, c1, c2, c3)
  879. end
  880.  
  881. ------------------------------------------------------------------------
  882. -- decodes a 4-char little-endian string into an instruction struct
  883. ------------------------------------------------------------------------
  884. function luaP:DecodeInst(x)
  885. local byte = string.byte
  886. local i = {}
  887. local I = byte(x, 1)
  888. local op = I % 64
  889. i.OP = op
  890. I = byte(x, 2) * 4 + (I - op) / 64 -- 2 bits of c0 left
  891. local a = I % 256
  892. i.A = a
  893. I = byte(x, 3) * 4 + (I - a) / 256 -- 2 bits of c1 left
  894. local c = I % 512
  895. i.C = c
  896. i.B = byte(x, 4) * 2 + (I - c) / 512 -- 1 bits of c2 left
  897. local opmode = self.OpMode[tonumber(string.sub(self.opmodes[op + 1], 7, 7))]
  898. if opmode ~= "iABC" then
  899. i.Bx = i.B * 512 + i.C
  900. end
  901. return i
  902. end
  903.  
  904. ------------------------------------------------------------------------
  905. -- Macros to operate RK indices
  906. -- * these use arithmetic instead of bit ops
  907. ------------------------------------------------------------------------
  908.  
  909. -- this bit 1 means constant (0 means register)
  910. luaP.BITRK = math.ldexp(1, luaP.SIZE_B - 1)
  911.  
  912. -- test whether value is a constant
  913. function luaP:ISK(x) return x >= self.BITRK end
  914.  
  915. -- gets the index of the constant
  916. function luaP:INDEXK(x) return x - self.BITRK end
  917.  
  918. luaP.MAXINDEXRK = luaP.BITRK - 1
  919.  
  920. -- code a constant index as a RK value
  921. function luaP:RKASK(x) return x + self.BITRK end
  922.  
  923. ------------------------------------------------------------------------
  924. -- invalid register that fits in 8 bits
  925. ------------------------------------------------------------------------
  926. luaP.NO_REG = luaP.MAXARG_A
  927.  
  928. ------------------------------------------------------------------------
  929. -- R(x) - register
  930. -- Kst(x) - constant (in constant table)
  931. -- RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
  932. ------------------------------------------------------------------------
  933.  
  934. ------------------------------------------------------------------------
  935. -- grep "ORDER OP" if you change these enums
  936. ------------------------------------------------------------------------
  937.  
  938. --[[--------------------------------------------------------------------
  939. Lua virtual machine opcodes (enum OpCode):
  940. ------------------------------------------------------------------------
  941. name args description
  942. ------------------------------------------------------------------------
  943. OP_MOVE A B R(A) := R(B)
  944. OP_LOADK A Bx R(A) := Kst(Bx)
  945. OP_LOADBOOL A B C R(A) := (Bool)B; if (C) pc++
  946. OP_LOADNIL A B R(A) := ... := R(B) := nil
  947. OP_GETUPVAL A B R(A) := UpValue[B]
  948. OP_GETGLOBAL A Bx R(A) := Gbl[Kst(Bx)]
  949. OP_GETTABLE A B C R(A) := R(B)[RK(C)]
  950. OP_SETGLOBAL A Bx Gbl[Kst(Bx)] := R(A)
  951. OP_SETUPVAL A B UpValue[B] := R(A)
  952. OP_SETTABLE A B C R(A)[RK(B)] := RK(C)
  953. OP_NEWTABLE A B C R(A) := {} (size = B,C)
  954. OP_SELF A B C R(A+1) := R(B); R(A) := R(B)[RK(C)]
  955. OP_ADD A B C R(A) := RK(B) + RK(C)
  956. OP_SUB A B C R(A) := RK(B) - RK(C)
  957. OP_MUL A B C R(A) := RK(B) * RK(C)
  958. OP_DIV A B C R(A) := RK(B) / RK(C)
  959. OP_MOD A B C R(A) := RK(B) % RK(C)
  960. OP_POW A B C R(A) := RK(B) ^ RK(C)
  961. OP_UNM A B R(A) := -R(B)
  962. OP_NOT A B R(A) := not R(B)
  963. OP_LEN A B R(A) := length of R(B)
  964. OP_CONCAT A B C R(A) := R(B).. ... ..R(C)
  965. OP_JMP sBx pc+=sBx
  966. OP_EQ A B C if ((RK(B) == RK(C)) ~= A) then pc++
  967. OP_LT A B C if ((RK(B) < RK(C)) ~= A) then pc++
  968. OP_LE A B C if ((RK(B) <= RK(C)) ~= A) then pc++
  969. OP_TEST A C if not (R(A) <=> C) then pc++
  970. OP_TESTSET A B C if (R(B) <=> C) then R(A) := R(B) else pc++
  971. OP_CALL A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))
  972. OP_TAILCALL A B C return R(A)(R(A+1), ... ,R(A+B-1))
  973. OP_RETURN A B return R(A), ... ,R(A+B-2) (see note)
  974. OP_FORLOOP A sBx R(A)+=R(A+2);
  975. if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }
  976. OP_FORPREP A sBx R(A)-=R(A+2); pc+=sBx
  977. OP_TFORLOOP A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
  978. if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++
  979. OP_SETLIST A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B
  980. OP_CLOSE A close all variables in the stack up to (>=) R(A)
  981. OP_CLOSURE A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))
  982. OP_VARARG A B R(A), R(A+1), ..., R(A+B-1) = vararg
  983. ----------------------------------------------------------------------]]
  984.  
  985. luaP.opnames = {} -- opcode names
  986. luaP.OpCode = {} -- lookup name -> number
  987. luaP.ROpCode = {} -- lookup number -> name
  988.  
  989. ------------------------------------------------------------------------
  990. -- ORDER OP
  991. ------------------------------------------------------------------------
  992. local i = 0
  993. for v in string.gmatch([[
  994. MOVE LOADK LOADBOOL LOADNIL GETUPVAL
  995. GETGLOBAL GETTABLE SETGLOBAL SETUPVAL SETTABLE
  996. NEWTABLE SELF ADD SUB MUL
  997. DIV MOD POW UNM NOT
  998. LEN CONCAT JMP EQ LT
  999. LE TEST TESTSET CALL TAILCALL
  1000. RETURN FORLOOP FORPREP TFORLOOP SETLIST
  1001. CLOSE CLOSURE VARARG
  1002. ]], "%S+") do
  1003. local n = "OP_"..v
  1004. luaP.opnames[i] = v
  1005. luaP.OpCode[n] = i
  1006. luaP.ROpCode[i] = n
  1007. i = i + 1
  1008. end
  1009. luaP.NUM_OPCODES = i
  1010.  
  1011. --[[
  1012. ===========================================================================
  1013. Notes:
  1014. (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
  1015. and can be 0: OP_CALL then sets 'top' to last_result+1, so
  1016. next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use 'top'.
  1017. (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
  1018. set top (like in OP_CALL with C == 0).
  1019. (*) In OP_RETURN, if (B == 0) then return up to 'top'
  1020. (*) In OP_SETLIST, if (B == 0) then B = 'top';
  1021. if (C == 0) then next 'instruction' is real C
  1022. (*) For comparisons, A specifies what condition the test should accept
  1023. (true or false).
  1024. (*) All 'skips' (pc++) assume that next instruction is a jump
  1025. ===========================================================================
  1026. --]]
  1027.  
  1028. --[[--------------------------------------------------------------------
  1029. masks for instruction properties. The format is:
  1030. bits 0-1: op mode
  1031. bits 2-3: C arg mode
  1032. bits 4-5: B arg mode
  1033. bit 6: instruction set register A
  1034. bit 7: operator is a test
  1035.  
  1036. for OpArgMask:
  1037. OpArgN - argument is not used
  1038. OpArgU - argument is used
  1039. OpArgR - argument is a register or a jump offset
  1040. OpArgK - argument is a constant or register/constant
  1041. ----------------------------------------------------------------------]]
  1042.  
  1043. -- was enum OpArgMask
  1044. luaP.OpArgMask = { OpArgN = 0, OpArgU = 1, OpArgR = 2, OpArgK = 3 }
  1045.  
  1046. ------------------------------------------------------------------------
  1047. -- e.g. to compare with symbols, luaP:getOpMode(...) == luaP.OpCode.iABC
  1048. -- * accepts opcode parameter as strings, e.g. "OP_MOVE"
  1049. ------------------------------------------------------------------------
  1050.  
  1051. function luaP:getOpMode(m)
  1052. return self.opmodes[self.OpCode[m]] % 4
  1053. end
  1054.  
  1055. function luaP:getBMode(m)
  1056. return math.floor(self.opmodes[self.OpCode[m]] / 16) % 4
  1057. end
  1058.  
  1059. function luaP:getCMode(m)
  1060. return math.floor(self.opmodes[self.OpCode[m]] / 4) % 4
  1061. end
  1062.  
  1063. function luaP:testAMode(m)
  1064. return math.floor(self.opmodes[self.OpCode[m]] / 64) % 2
  1065. end
  1066.  
  1067. function luaP:testTMode(m)
  1068. return math.floor(self.opmodes[self.OpCode[m]] / 128)
  1069. end
  1070.  
  1071. -- luaP_opnames[] is set above, as the luaP.opnames table
  1072.  
  1073. -- number of list items to accumulate before a SETLIST instruction
  1074. luaP.LFIELDS_PER_FLUSH = 50
  1075.  
  1076. ------------------------------------------------------------------------
  1077. -- build instruction properties array
  1078. -- * deliberately coded to look like the C equivalent
  1079. ------------------------------------------------------------------------
  1080. local function opmode(t, a, b, c, m)
  1081. local luaP = luaP
  1082. return t * 128 + a * 64 +
  1083. luaP.OpArgMask[b] * 16 + luaP.OpArgMask[c] * 4 + luaP.OpMode[m]
  1084. end
  1085.  
  1086. -- ORDER OP
  1087. luaP.opmodes = {
  1088. -- T A B C mode opcode
  1089. opmode(0, 1, "OpArgK", "OpArgN", "iABx"), -- OP_LOADK
  1090. opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_LOADBOOL
  1091. opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_LOADNIL
  1092. opmode(0, 1, "OpArgU", "OpArgN", "iABC"), -- OP_GETUPVAL
  1093. opmode(0, 1, "OpArgK", "OpArgN", "iABx"), -- OP_GETGLOBAL
  1094. opmode(0, 1, "OpArgR", "OpArgK", "iABC"), -- OP_GETTABLE
  1095. opmode(0, 0, "OpArgK", "OpArgN", "iABx"), -- OP_SETGLOBAL
  1096. opmode(0, 0, "OpArgU", "OpArgN", "iABC"), -- OP_SETUPVAL
  1097. opmode(0, 0, "OpArgK", "OpArgK", "iABC"), -- OP_SETTABLE
  1098. opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_NEWTABLE
  1099. opmode(0, 1, "OpArgR", "OpArgK", "iABC"), -- OP_SELF
  1100. opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_ADD
  1101. opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_SUB
  1102. opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_MUL
  1103. opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_DIV
  1104. opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_MOD
  1105. opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_POW
  1106. opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_UNM
  1107. opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_NOT
  1108. opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_LEN
  1109. opmode(0, 1, "OpArgR", "OpArgR", "iABC"), -- OP_CONCAT
  1110. opmode(0, 0, "OpArgR", "OpArgN", "iAsBx"), -- OP_JMP
  1111. opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_EQ
  1112. opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_LT
  1113. opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_LE
  1114. opmode(1, 1, "OpArgR", "OpArgU", "iABC"), -- OP_TEST
  1115. opmode(1, 1, "OpArgR", "OpArgU", "iABC"), -- OP_TESTSET
  1116. opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_CALL
  1117. opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_TAILCALL
  1118. opmode(0, 0, "OpArgU", "OpArgN", "iABC"), -- OP_RETURN
  1119. opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"), -- OP_FORLOOP
  1120. opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"), -- OP_FORPREP
  1121. opmode(1, 0, "OpArgN", "OpArgU", "iABC"), -- OP_TFORLOOP
  1122. opmode(0, 0, "OpArgU", "OpArgU", "iABC"), -- OP_SETLIST
  1123. opmode(0, 0, "OpArgN", "OpArgN", "iABC"), -- OP_CLOSE
  1124. opmode(0, 1, "OpArgU", "OpArgN", "iABx"), -- OP_CLOSURE
  1125. opmode(0, 1, "OpArgU", "OpArgN", "iABC"), -- OP_VARARG
  1126. }
  1127. -- an awkward way to set a zero-indexed table...
  1128. luaP.opmodes[0] =
  1129. opmode(0, 1, "OpArgR", "OpArgN", "iABC") -- OP_MOVE
  1130.  
  1131. return luaP
  1132. end
  1133. luaP=luaP()
  1134. local luaK = function ()
  1135. -- requires luaP, luaX, luaY
  1136. local luaK = {}
  1137. local luaP = luaP
  1138. local luaX = luaX
  1139.  
  1140. ------------------------------------------------------------------------
  1141. -- constants used by code generator
  1142. ------------------------------------------------------------------------
  1143. -- maximum stack for a Lua function
  1144. luaK.MAXSTACK = 250 -- (from llimits.h)
  1145.  
  1146. --[[--------------------------------------------------------------------
  1147. -- other functions
  1148. ----------------------------------------------------------------------]]
  1149.  
  1150. ------------------------------------------------------------------------
  1151. -- emulation of TValue macros (these are from lobject.h)
  1152. -- * TValue is a table since lcode passes references around
  1153. -- * tt member field removed, using Lua's type() instead
  1154. -- * for setsvalue, sethvalue, parameter L (deleted here) in lobject.h
  1155. -- is used in an assert for testing, see checkliveness(g,obj)
  1156. ------------------------------------------------------------------------
  1157. function luaK:ttisnumber(o)
  1158. if o then return type(o.value) == "number" else return false end
  1159. end
  1160. function luaK:nvalue(o) return o.value end
  1161. function luaK:setnilvalue(o) o.value = nil end
  1162. function luaK:setsvalue(o, x) o.value = x end
  1163. luaK.setnvalue = luaK.setsvalue
  1164. luaK.sethvalue = luaK.setsvalue
  1165. luaK.setbvalue = luaK.setsvalue
  1166.  
  1167. ------------------------------------------------------------------------
  1168. -- The luai_num* macros define the primitive operations over numbers.
  1169. -- * this is not the entire set of primitive operations from luaconf.h
  1170. -- * used in luaK:constfolding()
  1171. ------------------------------------------------------------------------
  1172. function luaK:numadd(a, b) return a + b end
  1173. function luaK:numsub(a, b) return a - b end
  1174. function luaK:nummul(a, b) return a * b end
  1175. function luaK:numdiv(a, b) return a / b end
  1176. function luaK:nummod(a, b) return a % b end
  1177. -- ((a) - floor((a)/(b))*(b)) /* actual, for reference */
  1178. function luaK:numpow(a, b) return a ^ b end
  1179. function luaK:numunm(a) return -a end
  1180. function luaK:numisnan(a) return not a == a end
  1181. -- a NaN cannot equal another NaN
  1182.  
  1183. --[[--------------------------------------------------------------------
  1184. -- code generator functions
  1185. ----------------------------------------------------------------------]]
  1186.  
  1187. ------------------------------------------------------------------------
  1188. -- Marks the end of a patch list. It is an invalid value both as an absolute
  1189. -- address, and as a list link (would link an element to itself).
  1190. ------------------------------------------------------------------------
  1191. luaK.NO_JUMP = -1
  1192.  
  1193. ------------------------------------------------------------------------
  1194. -- grep "ORDER OPR" if you change these enums
  1195. ------------------------------------------------------------------------
  1196. luaK.BinOpr = {
  1197. OPR_ADD = 0, OPR_SUB = 1, OPR_MUL = 2, OPR_DIV = 3, OPR_MOD = 4, OPR_POW = 5,
  1198. OPR_CONCAT = 6,
  1199. OPR_NE = 7, OPR_EQ = 8,
  1200. OPR_LT = 9, OPR_LE = 10, OPR_GT = 11, OPR_GE = 12,
  1201. OPR_AND = 13, OPR_OR = 14,
  1202. OPR_NOBINOPR = 15,
  1203. }
  1204.  
  1205. -- * UnOpr is used by luaK:prefix's op argument, but not directly used
  1206. -- because the function receives the symbols as strings, e.g. "OPR_NOT"
  1207. luaK.UnOpr = {
  1208. OPR_MINUS = 0, OPR_NOT = 1, OPR_LEN = 2, OPR_NOUNOPR = 3
  1209. }
  1210.  
  1211. ------------------------------------------------------------------------
  1212. -- returns the instruction object for given e (expdesc), was a macro
  1213. ------------------------------------------------------------------------
  1214. function luaK:getcode(fs, e)
  1215. return fs.f.code[e.info]
  1216. end
  1217.  
  1218. ------------------------------------------------------------------------
  1219. -- codes an instruction with a signed Bx (sBx) field, was a macro
  1220. -- * used in luaK:jump(), (lparser) luaY:forbody()
  1221. ------------------------------------------------------------------------
  1222. function luaK:codeAsBx(fs, o, A, sBx)
  1223. return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx)
  1224. end
  1225.  
  1226. ------------------------------------------------------------------------
  1227. -- set the expdesc e instruction for multiple returns, was a macro
  1228. ------------------------------------------------------------------------
  1229. function luaK:setmultret(fs, e)
  1230. self:setreturns(fs, e, luaY.LUA_MULTRET)
  1231. end
  1232.  
  1233. ------------------------------------------------------------------------
  1234. -- there is a jump if patch lists are not identical, was a macro
  1235. -- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val()
  1236. ------------------------------------------------------------------------
  1237. function luaK:hasjumps(e)
  1238. return e.t ~= e.f
  1239. end
  1240.  
  1241. ------------------------------------------------------------------------
  1242. -- true if the expression is a constant number (for constant folding)
  1243. -- * used in constfolding(), infix()
  1244. ------------------------------------------------------------------------
  1245. function luaK:isnumeral(e)
  1246. return e.k == "VKNUM" and e.t == self.NO_JUMP and e.f == self.NO_JUMP
  1247. end
  1248.  
  1249. ------------------------------------------------------------------------
  1250. -- codes loading of nil, optimization done if consecutive locations
  1251. -- * used in luaK:discharge2reg(), (lparser) luaY:adjust_assign()
  1252. ------------------------------------------------------------------------
  1253. function luaK:_nil(fs, from, n)
  1254. if fs.pc > fs.lasttarget then -- no jumps to current position?
  1255. if fs.pc == 0 then -- function start?
  1256. if from >= fs.nactvar then
  1257. return -- positions are already clean
  1258. end
  1259. else
  1260. local previous = fs.f.code[fs.pc - 1]
  1261. if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then
  1262. local pfrom = luaP:GETARG_A(previous)
  1263. local pto = luaP:GETARG_B(previous)
  1264. if pfrom <= from and from <= pto + 1 then -- can connect both?
  1265. if from + n - 1 > pto then
  1266. luaP:SETARG_B(previous, from + n - 1)
  1267. end
  1268. return
  1269. end
  1270. end
  1271. end
  1272. end
  1273. self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization
  1274. end
  1275.  
  1276. ------------------------------------------------------------------------
  1277. --
  1278. -- * used in multiple locations
  1279. ------------------------------------------------------------------------
  1280. function luaK:jump(fs)
  1281. local jpc = fs.jpc -- save list of jumps to here
  1282. fs.jpc = self.NO_JUMP
  1283. local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP)
  1284. j = self:concat(fs, j, jpc) -- keep them on hold
  1285. return j
  1286. end
  1287.  
  1288. ------------------------------------------------------------------------
  1289. -- codes a RETURN instruction
  1290. -- * used in luaY:close_func(), luaY:retstat()
  1291. ------------------------------------------------------------------------
  1292. function luaK:ret(fs, first, nret)
  1293. self:codeABC(fs, "OP_RETURN", first, nret + 1, 0)
  1294. end
  1295.  
  1296. ------------------------------------------------------------------------
  1297. --
  1298. -- * used in luaK:jumponcond(), luaK:codecomp()
  1299. ------------------------------------------------------------------------
  1300. function luaK:condjump(fs, op, A, B, C)
  1301. self:codeABC(fs, op, A, B, C)
  1302. return self:jump(fs)
  1303. end
  1304.  
  1305. ------------------------------------------------------------------------
  1306. --
  1307. -- * used in luaK:patchlistaux(), luaK:concat()
  1308. ------------------------------------------------------------------------
  1309. function luaK:fixjump(fs, pc, dest)
  1310. local jmp = fs.f.code[pc]
  1311. local offset = dest - (pc + 1)
  1312. assert(dest ~= self.NO_JUMP)
  1313. if math.abs(offset) > luaP.MAXARG_sBx then
  1314. luaX:syntaxerror(fs.ls, "control structure too long")
  1315. end
  1316. luaP:SETARG_sBx(jmp, offset)
  1317. end
  1318.  
  1319. ------------------------------------------------------------------------
  1320. -- returns current 'pc' and marks it as a jump target (to avoid wrong
  1321. -- optimizations with consecutive instructions not in the same basic block).
  1322. -- * used in multiple locations
  1323. -- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL
  1324. ------------------------------------------------------------------------
  1325. function luaK:getlabel(fs)
  1326. fs.lasttarget = fs.pc
  1327. return fs.pc
  1328. end
  1329.  
  1330. ------------------------------------------------------------------------
  1331. --
  1332. -- * used in luaK:need_value(), luaK:removevalues(), luaK:patchlistaux(),
  1333. -- luaK:concat()
  1334. ------------------------------------------------------------------------
  1335. function luaK:getjump(fs, pc)
  1336. local offset = luaP:GETARG_sBx(fs.f.code[pc])
  1337. if offset == self.NO_JUMP then -- point to itself represents end of list
  1338. return self.NO_JUMP -- end of list
  1339. else
  1340. return (pc + 1) + offset -- turn offset into absolute position
  1341. end
  1342. end
  1343.  
  1344. ------------------------------------------------------------------------
  1345. --
  1346. -- * used in luaK:need_value(), luaK:patchtestreg(), luaK:invertjump()
  1347. ------------------------------------------------------------------------
  1348. function luaK:getjumpcontrol(fs, pc)
  1349. local pi = fs.f.code[pc]
  1350. local ppi = fs.f.code[pc - 1]
  1351. if pc >= 1 and luaP:testTMode(luaP:GET_OPCODE(ppi)) ~= 0 then
  1352. return ppi
  1353. else
  1354. return pi
  1355. end
  1356. end
  1357.  
  1358. ------------------------------------------------------------------------
  1359. -- check whether list has any jump that do not produce a value
  1360. -- (or produce an inverted value)
  1361. -- * return value changed to boolean
  1362. -- * used only in luaK:exp2reg()
  1363. ------------------------------------------------------------------------
  1364. function luaK:need_value(fs, list)
  1365. while list ~= self.NO_JUMP do
  1366. local i = self:getjumpcontrol(fs, list)
  1367. if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then return true end
  1368. list = self:getjump(fs, list)
  1369. end
  1370. return false -- not found
  1371. end
  1372.  
  1373. ------------------------------------------------------------------------
  1374. --
  1375. -- * used in luaK:removevalues(), luaK:patchlistaux()
  1376. ------------------------------------------------------------------------
  1377. function luaK:patchtestreg(fs, node, reg)
  1378. local i = self:getjumpcontrol(fs, node)
  1379. if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then
  1380. return false -- cannot patch other instructions
  1381. end
  1382. if reg ~= luaP.NO_REG and reg ~= luaP:GETARG_B(i) then
  1383. luaP:SETARG_A(i, reg)
  1384. else -- no register to put value or register already has the value
  1385. -- due to use of a table as i, i cannot be replaced by another table
  1386. -- so the following is required; there is no change to ARG_C
  1387. luaP:SET_OPCODE(i, "OP_TEST")
  1388. local b = luaP:GETARG_B(i)
  1389. luaP:SETARG_A(i, b)
  1390. luaP:SETARG_B(i, 0)
  1391. -- *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); /* C */
  1392. end
  1393. return true
  1394. end
  1395.  
  1396. ------------------------------------------------------------------------
  1397. --
  1398. -- * used only in luaK:codenot()
  1399. ------------------------------------------------------------------------
  1400. function luaK:removevalues(fs, list)
  1401. while list ~= self.NO_JUMP do
  1402. self:patchtestreg(fs, list, luaP.NO_REG)
  1403. list = self:getjump(fs, list)
  1404. end
  1405. end
  1406.  
  1407. ------------------------------------------------------------------------
  1408. --
  1409. -- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg()
  1410. ------------------------------------------------------------------------
  1411. function luaK:patchlistaux(fs, list, vtarget, reg, dtarget)
  1412. while list ~= self.NO_JUMP do
  1413. local _next = self:getjump(fs, list)
  1414. if self:patchtestreg(fs, list, reg) then
  1415. self:fixjump(fs, list, vtarget)
  1416. else
  1417. self:fixjump(fs, list, dtarget) -- jump to default target
  1418. end
  1419. list = _next
  1420. end
  1421. end
  1422.  
  1423. ------------------------------------------------------------------------
  1424. --
  1425. -- * used only in luaK:code()
  1426. ------------------------------------------------------------------------
  1427. function luaK:dischargejpc(fs)
  1428. self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc)
  1429. fs.jpc = self.NO_JUMP
  1430. end
  1431.  
  1432. ------------------------------------------------------------------------
  1433. --
  1434. -- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody()
  1435. ------------------------------------------------------------------------
  1436. function luaK:patchlist(fs, list, target)
  1437. if target == fs.pc then
  1438. self:patchtohere(fs, list)
  1439. else
  1440. assert(target < fs.pc)
  1441. self:patchlistaux(fs, list, target, luaP.NO_REG, target)
  1442. end
  1443. end
  1444.  
  1445. ------------------------------------------------------------------------
  1446. --
  1447. -- * used in multiple locations
  1448. ------------------------------------------------------------------------
  1449. function luaK:patchtohere(fs, list)
  1450. self:getlabel(fs)
  1451. fs.jpc = self:concat(fs, fs.jpc, list)
  1452. end
  1453.  
  1454. ------------------------------------------------------------------------
  1455. -- * l1 was a pointer, now l1 is returned and callee assigns the value
  1456. -- * used in multiple locations
  1457. ------------------------------------------------------------------------
  1458. function luaK:concat(fs, l1, l2)
  1459. if l2 == self.NO_JUMP then return l1
  1460. elseif l1 == self.NO_JUMP then
  1461. return l2
  1462. else
  1463. local list = l1
  1464. local _next = self:getjump(fs, list)
  1465. while _next ~= self.NO_JUMP do -- find last element
  1466. list = _next
  1467. _next = self:getjump(fs, list)
  1468. end
  1469. self:fixjump(fs, list, l2)
  1470. end
  1471. return l1
  1472. end
  1473.  
  1474. ------------------------------------------------------------------------
  1475. --
  1476. -- * used in luaK:reserveregs(), (lparser) luaY:forlist()
  1477. ------------------------------------------------------------------------
  1478. function luaK:checkstack(fs, n)
  1479. local newstack = fs.freereg + n
  1480. if newstack > fs.f.maxstacksize then
  1481. if newstack >= self.MAXSTACK then
  1482. luaX:syntaxerror(fs.ls, "function or expression too complex")
  1483. end
  1484. fs.f.maxstacksize = newstack
  1485. end
  1486. end
  1487.  
  1488. ------------------------------------------------------------------------
  1489. --
  1490. -- * used in multiple locations
  1491. ------------------------------------------------------------------------
  1492. function luaK:reserveregs(fs, n)
  1493. self:checkstack(fs, n)
  1494. fs.freereg = fs.freereg + n
  1495. end
  1496.  
  1497. ------------------------------------------------------------------------
  1498. --
  1499. -- * used in luaK:freeexp(), luaK:dischargevars()
  1500. ------------------------------------------------------------------------
  1501. function luaK:freereg(fs, reg)
  1502. if not luaP:ISK(reg) and reg >= fs.nactvar then
  1503. fs.freereg = fs.freereg - 1
  1504. assert(reg == fs.freereg)
  1505. end
  1506. end
  1507.  
  1508. ------------------------------------------------------------------------
  1509. --
  1510. -- * used in multiple locations
  1511. ------------------------------------------------------------------------
  1512. function luaK:freeexp(fs, e)
  1513. if e.k == "VNONRELOC" then
  1514. self:freereg(fs, e.info)
  1515. end
  1516. end
  1517.  
  1518. ------------------------------------------------------------------------
  1519. -- * TODO NOTE implementation is not 100% correct, since the assert fails
  1520. -- * luaH_set, setobj deleted; direct table access used instead
  1521. -- * used in luaK:stringK(), luaK:numberK(), luaK:boolK(), luaK:nilK()
  1522. ------------------------------------------------------------------------
  1523. function luaK:addk(fs, k, v)
  1524. local L = fs.L
  1525. local idx = fs.h[k.value]
  1526. --TValue *idx = luaH_set(L, fs->h, k); /* C */
  1527. local f = fs.f
  1528. if self:ttisnumber(idx) then
  1529. --TODO this assert currently FAILS (last tested for 5.0.2)
  1530. --assert(fs.f.k[self:nvalue(idx)] == v)
  1531. --assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); /* C */
  1532. return self:nvalue(idx)
  1533. else -- constant not found; create a new entry
  1534. idx = {}
  1535. self:setnvalue(idx, fs.nk)
  1536. fs.h[k.value] = idx
  1537. -- setnvalue(idx, cast_num(fs->nk)); /* C */
  1538. luaY:growvector(L, f.k, fs.nk, f.sizek, nil,
  1539. luaP.MAXARG_Bx, "constant table overflow")
  1540. -- loop to initialize empty f.k positions not required
  1541. f.k[fs.nk] = v
  1542. -- setobj(L, &f->k[fs->nk], v); /* C */
  1543. -- luaC_barrier(L, f, v); /* GC */
  1544. local nk = fs.nk
  1545. fs.nk = fs.nk + 1
  1546. return nk
  1547. end
  1548.  
  1549. end
  1550.  
  1551. ------------------------------------------------------------------------
  1552. -- creates and sets a string object
  1553. -- * used in (lparser) luaY:codestring(), luaY:singlevar()
  1554. ------------------------------------------------------------------------
  1555. function luaK:stringK(fs, s)
  1556. local o = {} -- TValue
  1557. self:setsvalue(o, s)
  1558. return self:addk(fs, o, o)
  1559. end
  1560.  
  1561. ------------------------------------------------------------------------
  1562. -- creates and sets a number object
  1563. -- * used in luaK:prefix() for negative (or negation of) numbers
  1564. -- * used in (lparser) luaY:simpleexp(), luaY:fornum()
  1565. ------------------------------------------------------------------------
  1566. function luaK:numberK(fs, r)
  1567. local o = {} -- TValue
  1568. self:setnvalue(o, r)
  1569. return self:addk(fs, o, o)
  1570. end
  1571.  
  1572. ------------------------------------------------------------------------
  1573. -- creates and sets a boolean object
  1574. -- * used only in luaK:exp2RK()
  1575. ------------------------------------------------------------------------
  1576. function luaK:boolK(fs, b)
  1577. local o = {} -- TValue
  1578. self:setbvalue(o, b)
  1579. return self:addk(fs, o, o)
  1580. end
  1581.  
  1582. ------------------------------------------------------------------------
  1583. -- creates and sets a nil object
  1584. -- * used only in luaK:exp2RK()
  1585. ------------------------------------------------------------------------
  1586. function luaK:nilK(fs)
  1587. local k, v = {}, {} -- TValue
  1588. self:setnilvalue(v)
  1589. -- cannot use nil as key; instead use table itself to represent nil
  1590. self:sethvalue(k, fs.h)
  1591. return self:addk(fs, k, v)
  1592. end
  1593.  
  1594. ------------------------------------------------------------------------
  1595. --
  1596. -- * used in luaK:setmultret(), (lparser) luaY:adjust_assign()
  1597. ------------------------------------------------------------------------
  1598. function luaK:setreturns(fs, e, nresults)
  1599. if e.k == "VCALL" then -- expression is an open function call?
  1600. luaP:SETARG_C(self:getcode(fs, e), nresults + 1)
  1601. elseif e.k == "VVARARG" then
  1602. luaP:SETARG_B(self:getcode(fs, e), nresults + 1);
  1603. luaP:SETARG_A(self:getcode(fs, e), fs.freereg);
  1604. luaK:reserveregs(fs, 1)
  1605. end
  1606. end
  1607.  
  1608. ------------------------------------------------------------------------
  1609. --
  1610. -- * used in luaK:dischargevars(), (lparser) luaY:assignment()
  1611. ------------------------------------------------------------------------
  1612. function luaK:setoneret(fs, e)
  1613. if e.k == "VCALL" then -- expression is an open function call?
  1614. e.k = "VNONRELOC"
  1615. e.info = luaP:GETARG_A(self:getcode(fs, e))
  1616. elseif e.k == "VVARARG" then
  1617. luaP:SETARG_B(self:getcode(fs, e), 2)
  1618. e.k = "VRELOCABLE" -- can relocate its simple result
  1619. end
  1620. end
  1621.  
  1622. ------------------------------------------------------------------------
  1623. --
  1624. -- * used in multiple locations
  1625. ------------------------------------------------------------------------
  1626. function luaK:dischargevars(fs, e)
  1627. local k = e.k
  1628. if k == "VLOCAL" then
  1629. e.k = "VNONRELOC"
  1630. elseif k == "VUPVAL" then
  1631. e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0)
  1632. e.k = "VRELOCABLE"
  1633. elseif k == "VGLOBAL" then
  1634. e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info)
  1635. e.k = "VRELOCABLE"
  1636. elseif k == "VINDEXED" then
  1637. self:freereg(fs, e.aux)
  1638. self:freereg(fs, e.info)
  1639. e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux)
  1640. e.k = "VRELOCABLE"
  1641. elseif k == "VVARARG" or k == "VCALL" then
  1642. self:setoneret(fs, e)
  1643. else
  1644. -- there is one value available (somewhere)
  1645. end
  1646. end
  1647.  
  1648. ------------------------------------------------------------------------
  1649. --
  1650. -- * used only in luaK:exp2reg()
  1651. ------------------------------------------------------------------------
  1652. function luaK:code_label(fs, A, b, jump)
  1653. self:getlabel(fs) -- those instructions may be jump targets
  1654. return self:codeABC(fs, "OP_LOADBOOL", A, b, jump)
  1655. end
  1656.  
  1657. ------------------------------------------------------------------------
  1658. --
  1659. -- * used in luaK:discharge2anyreg(), luaK:exp2reg()
  1660. ------------------------------------------------------------------------
  1661. function luaK:discharge2reg(fs, e, reg)
  1662. self:dischargevars(fs, e)
  1663. local k = e.k
  1664. if k == "VNIL" then
  1665. self:_nil(fs, reg, 1)
  1666. elseif k == "VFALSE" or k == "VTRUE" then
  1667. self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0)
  1668. elseif k == "VK" then
  1669. self:codeABx(fs, "OP_LOADK", reg, e.info)
  1670. elseif k == "VKNUM" then
  1671. self:codeABx(fs, "OP_LOADK", reg, self:numberK(fs, e.nval))
  1672. elseif k == "VRELOCABLE" then
  1673. local pc = self:getcode(fs, e)
  1674. luaP:SETARG_A(pc, reg)
  1675. elseif k == "VNONRELOC" then
  1676. if reg ~= e.info then
  1677. self:codeABC(fs, "OP_MOVE", reg, e.info, 0)
  1678. end
  1679. else
  1680. assert(e.k == "VVOID" or e.k == "VJMP")
  1681. return -- nothing to do...
  1682. end
  1683. e.info = reg
  1684. e.k = "VNONRELOC"
  1685. end
  1686.  
  1687. ------------------------------------------------------------------------
  1688. --
  1689. -- * used in luaK:jumponcond(), luaK:codenot()
  1690. ------------------------------------------------------------------------
  1691. function luaK:discharge2anyreg(fs, e)
  1692. if e.k ~= "VNONRELOC" then
  1693. self:reserveregs(fs, 1)
  1694. self:discharge2reg(fs, e, fs.freereg - 1)
  1695. end
  1696. end
  1697.  
  1698. ------------------------------------------------------------------------
  1699. --
  1700. -- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar()
  1701. ------------------------------------------------------------------------
  1702. function luaK:exp2reg(fs, e, reg)
  1703. self:discharge2reg(fs, e, reg)
  1704. if e.k == "VJMP" then
  1705. e.t = self:concat(fs, e.t, e.info) -- put this jump in 't' list
  1706. end
  1707. if self:hasjumps(e) then
  1708. local final -- position after whole expression
  1709. local p_f = self.NO_JUMP -- position of an eventual LOAD false
  1710. local p_t = self.NO_JUMP -- position of an eventual LOAD true
  1711. if self:need_value(fs, e.t) or self:need_value(fs, e.f) then
  1712. local fj = (e.k == "VJMP") and self.NO_JUMP or self:jump(fs)
  1713. p_f = self:code_label(fs, reg, 0, 1)
  1714. p_t = self:code_label(fs, reg, 1, 0)
  1715. self:patchtohere(fs, fj)
  1716. end
  1717. final = self:getlabel(fs)
  1718. self:patchlistaux(fs, e.f, final, reg, p_f)
  1719. self:patchlistaux(fs, e.t, final, reg, p_t)
  1720. end
  1721. e.f, e.t = self.NO_JUMP, self.NO_JUMP
  1722. e.info = reg
  1723. e.k = "VNONRELOC"
  1724. end
  1725.  
  1726. ------------------------------------------------------------------------
  1727. --
  1728. -- * used in multiple locations
  1729. ------------------------------------------------------------------------
  1730. function luaK:exp2nextreg(fs, e)
  1731. self:dischargevars(fs, e)
  1732. self:freeexp(fs, e)
  1733. self:reserveregs(fs, 1)
  1734. self:exp2reg(fs, e, fs.freereg - 1)
  1735. end
  1736.  
  1737. ------------------------------------------------------------------------
  1738. --
  1739. -- * used in multiple locations
  1740. ------------------------------------------------------------------------
  1741. function luaK:exp2anyreg(fs, e)
  1742. self:dischargevars(fs, e)
  1743. if e.k == "VNONRELOC" then
  1744. if not self:hasjumps(e) then -- exp is already in a register
  1745. return e.info
  1746. end
  1747. if e.info >= fs.nactvar then -- reg. is not a local?
  1748. self:exp2reg(fs, e, e.info) -- put value on it
  1749. return e.info
  1750. end
  1751. end
  1752. self:exp2nextreg(fs, e) -- default
  1753. return e.info
  1754. end
  1755.  
  1756. ------------------------------------------------------------------------
  1757. --
  1758. -- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix()
  1759. -- * used in (lparser) luaY:yindex()
  1760. ------------------------------------------------------------------------
  1761. function luaK:exp2val(fs, e)
  1762. if self:hasjumps(e) then
  1763. self:exp2anyreg(fs, e)
  1764. else
  1765. self:dischargevars(fs, e)
  1766. end
  1767. end
  1768.  
  1769. ------------------------------------------------------------------------
  1770. --
  1771. -- * used in multiple locations
  1772. ------------------------------------------------------------------------
  1773. function luaK:exp2RK(fs, e)
  1774. self:exp2val(fs, e)
  1775. local k = e.k
  1776. if k == "VKNUM" or k == "VTRUE" or k == "VFALSE" or k == "VNIL" then
  1777. if fs.nk <= luaP.MAXINDEXRK then -- constant fit in RK operand?
  1778. -- converted from a 2-deep ternary operator expression
  1779. if e.k == "VNIL" then
  1780. e.info = self:nilK(fs)
  1781. else
  1782. e.info = (e.k == "VKNUM") and self:numberK(fs, e.nval)
  1783. or self:boolK(fs, e.k == "VTRUE")
  1784. end
  1785. e.k = "VK"
  1786. return luaP:RKASK(e.info)
  1787. end
  1788. elseif k == "VK" then
  1789. if e.info <= luaP.MAXINDEXRK then -- constant fit in argC?
  1790. return luaP:RKASK(e.info)
  1791. end
  1792. else
  1793. -- default
  1794. end
  1795. -- not a constant in the right range: put it in a register
  1796. return self:exp2anyreg(fs, e)
  1797. end
  1798.  
  1799. ------------------------------------------------------------------------
  1800. --
  1801. -- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat()
  1802. ------------------------------------------------------------------------
  1803. function luaK:storevar(fs, var, ex)
  1804. local k = var.k
  1805. if k == "VLOCAL" then
  1806. self:freeexp(fs, ex)
  1807. self:exp2reg(fs, ex, var.info)
  1808. return
  1809. elseif k == "VUPVAL" then
  1810. local e = self:exp2anyreg(fs, ex)
  1811. self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0)
  1812. elseif k == "VGLOBAL" then
  1813. local e = self:exp2anyreg(fs, ex)
  1814. self:codeABx(fs, "OP_SETGLOBAL", e, var.info)
  1815. elseif k == "VINDEXED" then
  1816. local e = self:exp2RK(fs, ex)
  1817. self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e)
  1818. else
  1819. assert(0) -- invalid var kind to store
  1820. end
  1821. self:freeexp(fs, ex)
  1822. end
  1823.  
  1824. ------------------------------------------------------------------------
  1825. --
  1826. -- * used only in (lparser) luaY:primaryexp()
  1827. ------------------------------------------------------------------------
  1828. function luaK:_self(fs, e, key)
  1829. self:exp2anyreg(fs, e)
  1830. self:freeexp(fs, e)
  1831. local func = fs.freereg
  1832. self:reserveregs(fs, 2)
  1833. self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key))
  1834. self:freeexp(fs, key)
  1835. e.info = func
  1836. e.k = "VNONRELOC"
  1837. end
  1838.  
  1839. ------------------------------------------------------------------------
  1840. --
  1841. -- * used in luaK:goiftrue(), luaK:codenot()
  1842. ------------------------------------------------------------------------
  1843. function luaK:invertjump(fs, e)
  1844. local pc = self:getjumpcontrol(fs, e.info)
  1845. assert(luaP:testTMode(luaP:GET_OPCODE(pc)) ~= 0 and
  1846. luaP:GET_OPCODE(pc) ~= "OP_TESTSET" and
  1847. luaP:GET_OPCODE(pc) ~= "OP_TEST")
  1848. luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0)
  1849. end
  1850.  
  1851. ------------------------------------------------------------------------
  1852. --
  1853. -- * used in luaK:goiftrue(), luaK:goiffalse()
  1854. ------------------------------------------------------------------------
  1855. function luaK:jumponcond(fs, e, cond)
  1856. if e.k == "VRELOCABLE" then
  1857. local ie = self:getcode(fs, e)
  1858. if luaP:GET_OPCODE(ie) == "OP_NOT" then
  1859. fs.pc = fs.pc - 1 -- remove previous OP_NOT
  1860. return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), 0, cond and 0 or 1)
  1861. end
  1862. -- else go through
  1863. end
  1864. self:discharge2anyreg(fs, e)
  1865. self:freeexp(fs, e)
  1866. return self:condjump(fs, "OP_TESTSET", luaP.NO_REG, e.info, cond and 1 or 0)
  1867. end
  1868.  
  1869. ------------------------------------------------------------------------
  1870. --
  1871. -- * used in luaK:infix(), (lparser) luaY:cond()
  1872. ------------------------------------------------------------------------
  1873. function luaK:goiftrue(fs, e)
  1874. local pc -- pc of last jump
  1875. self:dischargevars(fs, e)
  1876. local k = e.k
  1877. if k == "VK" or k == "VKNUM" or k == "VTRUE" then
  1878. pc = self.NO_JUMP -- always true; do nothing
  1879. elseif k == "VFALSE" then
  1880. pc = self:jump(fs) -- always jump
  1881. elseif k == "VJMP" then
  1882. self:invertjump(fs, e)
  1883. pc = e.info
  1884. else
  1885. pc = self:jumponcond(fs, e, false)
  1886. end
  1887. e.f = self:concat(fs, e.f, pc) -- insert last jump in `f' list
  1888. self:patchtohere(fs, e.t)
  1889. e.t = self.NO_JUMP
  1890. end
  1891.  
  1892. ------------------------------------------------------------------------
  1893. --
  1894. -- * used in luaK:infix()
  1895. ------------------------------------------------------------------------
  1896. function luaK:goiffalse(fs, e)
  1897. local pc -- pc of last jump
  1898. self:dischargevars(fs, e)
  1899. local k = e.k
  1900. if k == "VNIL" or k == "VFALSE"then
  1901. pc = self.NO_JUMP -- always false; do nothing
  1902. elseif k == "VTRUE" then
  1903. pc = self:jump(fs) -- always jump
  1904. elseif k == "VJMP" then
  1905. pc = e.info
  1906. else
  1907. pc = self:jumponcond(fs, e, true)
  1908. end
  1909. e.t = self:concat(fs, e.t, pc) -- insert last jump in `t' list
  1910. self:patchtohere(fs, e.f)
  1911. e.f = self.NO_JUMP
  1912. end
  1913.  
  1914. ------------------------------------------------------------------------
  1915. --
  1916. -- * used only in luaK:prefix()
  1917. ------------------------------------------------------------------------
  1918. function luaK:codenot(fs, e)
  1919. self:dischargevars(fs, e)
  1920. local k = e.k
  1921. if k == "VNIL" or k == "VFALSE" then
  1922. e.k = "VTRUE"
  1923. elseif k == "VK" or k == "VKNUM" or k == "VTRUE" then
  1924. e.k = "VFALSE"
  1925. elseif k == "VJMP" then
  1926. self:invertjump(fs, e)
  1927. elseif k == "VRELOCABLE" or k == "VNONRELOC" then
  1928. self:discharge2anyreg(fs, e)
  1929. self:freeexp(fs, e)
  1930. e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0)
  1931. e.k = "VRELOCABLE"
  1932. else
  1933. assert(0) -- cannot happen
  1934. end
  1935. -- interchange true and false lists
  1936. e.f, e.t = e.t, e.f
  1937. self:removevalues(fs, e.f)
  1938. self:removevalues(fs, e.t)
  1939. end
  1940.  
  1941. ------------------------------------------------------------------------
  1942. --
  1943. -- * used in (lparser) luaY:field(), luaY:primaryexp()
  1944. ------------------------------------------------------------------------
  1945. function luaK:indexed(fs, t, k)
  1946. t.aux = self:exp2RK(fs, k)
  1947. t.k = "VINDEXED"
  1948. end
  1949.  
  1950. ------------------------------------------------------------------------
  1951. --
  1952. -- * used only in luaK:codearith()
  1953. ------------------------------------------------------------------------
  1954. function luaK:constfolding(op, e1, e2)
  1955. local r
  1956. if not self:isnumeral(e1) or not self:isnumeral(e2) then return false end
  1957. local v1 = e1.nval
  1958. local v2 = e2.nval
  1959. if op == "OP_ADD" then
  1960. r = self:numadd(v1, v2)
  1961. elseif op == "OP_SUB" then
  1962. r = self:numsub(v1, v2)
  1963. elseif op == "OP_MUL" then
  1964. r = self:nummul(v1, v2)
  1965. elseif op == "OP_DIV" then
  1966. if v2 == 0 then return false end -- do not attempt to divide by 0
  1967. r = self:numdiv(v1, v2)
  1968. elseif op == "OP_MOD" then
  1969. if v2 == 0 then return false end -- do not attempt to divide by 0
  1970. r = self:nummod(v1, v2)
  1971. elseif op == "OP_POW" then
  1972. r = self:numpow(v1, v2)
  1973. elseif op == "OP_UNM" then
  1974. r = self:numunm(v1)
  1975. elseif op == "OP_LEN" then
  1976. return false -- no constant folding for 'len'
  1977. else
  1978. assert(0)
  1979. r = 0
  1980. end
  1981. if self:numisnan(r) then return false end -- do not attempt to produce NaN
  1982. e1.nval = r
  1983. return true
  1984. end
  1985.  
  1986. ------------------------------------------------------------------------
  1987. --
  1988. -- * used in luaK:prefix(), luaK:posfix()
  1989. ------------------------------------------------------------------------
  1990. function luaK:codearith(fs, op, e1, e2)
  1991. if self:constfolding(op, e1, e2) then
  1992. return
  1993. else
  1994. local o2 = (op ~= "OP_UNM" and op ~= "OP_LEN") and self:exp2RK(fs, e2) or 0
  1995. local o1 = self:exp2RK(fs, e1)
  1996. if o1 > o2 then
  1997. self:freeexp(fs, e1)
  1998. self:freeexp(fs, e2)
  1999. else
  2000. self:freeexp(fs, e2)
  2001. self:freeexp(fs, e1)
  2002. end
  2003. e1.info = self:codeABC(fs, op, 0, o1, o2)
  2004. e1.k = "VRELOCABLE"
  2005. end
  2006. end
  2007.  
  2008. ------------------------------------------------------------------------
  2009. --
  2010. -- * used only in luaK:posfix()
  2011. ------------------------------------------------------------------------
  2012. function luaK:codecomp(fs, op, cond, e1, e2)
  2013. local o1 = self:exp2RK(fs, e1)
  2014. local o2 = self:exp2RK(fs, e2)
  2015. self:freeexp(fs, e2)
  2016. self:freeexp(fs, e1)
  2017. if cond == 0 and op ~= "OP_EQ" then
  2018. -- exchange args to replace by `<' or `<='
  2019. o1, o2 = o2, o1 -- o1 <==> o2
  2020. cond = 1
  2021. end
  2022. e1.info = self:condjump(fs, op, cond, o1, o2)
  2023. e1.k = "VJMP"
  2024. end
  2025.  
  2026. ------------------------------------------------------------------------
  2027. --
  2028. -- * used only in (lparser) luaY:subexpr()
  2029. ------------------------------------------------------------------------
  2030. function luaK:prefix(fs, op, e)
  2031. local e2 = {} -- expdesc
  2032. e2.t, e2.f = self.NO_JUMP, self.NO_JUMP
  2033. e2.k = "VKNUM"
  2034. e2.nval = 0
  2035. if op == "OPR_MINUS" then
  2036. if not self:isnumeral(e) then
  2037. self:exp2anyreg(fs, e) -- cannot operate on non-numeric constants
  2038. end
  2039. self:codearith(fs, "OP_UNM", e, e2)
  2040. elseif op == "OPR_NOT" then
  2041. self:codenot(fs, e)
  2042. elseif op == "OPR_LEN" then
  2043. self:exp2anyreg(fs, e) -- cannot operate on constants
  2044. self:codearith(fs, "OP_LEN", e, e2)
  2045. else
  2046. assert(0)
  2047. end
  2048. end
  2049.  
  2050. ------------------------------------------------------------------------
  2051. --
  2052. -- * used only in (lparser) luaY:subexpr()
  2053. ------------------------------------------------------------------------
  2054. function luaK:infix(fs, op, v)
  2055. if op == "OPR_AND" then
  2056. self:goiftrue(fs, v)
  2057. elseif op == "OPR_OR" then
  2058. self:goiffalse(fs, v)
  2059. elseif op == "OPR_CONCAT" then
  2060. self:exp2nextreg(fs, v) -- operand must be on the 'stack'
  2061. elseif op == "OPR_ADD" or op == "OPR_SUB" or
  2062. op == "OPR_MUL" or op == "OPR_DIV" or
  2063. op == "OPR_MOD" or op == "OPR_POW" then
  2064. if not self:isnumeral(v) then self:exp2RK(fs, v) end
  2065. else
  2066. self:exp2RK(fs, v)
  2067. end
  2068. end
  2069.  
  2070. ------------------------------------------------------------------------
  2071. --
  2072. -- * used only in (lparser) luaY:subexpr()
  2073. ------------------------------------------------------------------------
  2074. -- table lookups to simplify testing
  2075. luaK.arith_op = {
  2076. OPR_ADD = "OP_ADD", OPR_SUB = "OP_SUB", OPR_MUL = "OP_MUL",
  2077. OPR_DIV = "OP_DIV", OPR_MOD = "OP_MOD", OPR_POW = "OP_POW",
  2078. }
  2079. luaK.comp_op = {
  2080. OPR_EQ = "OP_EQ", OPR_NE = "OP_EQ", OPR_LT = "OP_LT",
  2081. OPR_LE = "OP_LE", OPR_GT = "OP_LT", OPR_GE = "OP_LE",
  2082. }
  2083. luaK.comp_cond = {
  2084. OPR_EQ = 1, OPR_NE = 0, OPR_LT = 1,
  2085. OPR_LE = 1, OPR_GT = 0, OPR_GE = 0,
  2086. }
  2087. function luaK:posfix(fs, op, e1, e2)
  2088. -- needed because e1 = e2 doesn't copy values...
  2089. -- * in 5.0.x, only k/info/aux/t/f copied, t for AND, f for OR
  2090. -- but here, all elements are copied for completeness' sake
  2091. local function copyexp(e1, e2)
  2092. e1.k = e2.k
  2093. e1.info = e2.info; e1.aux = e2.aux
  2094. e1.nval = e2.nval
  2095. e1.t = e2.t; e1.f = e2.f
  2096. end
  2097. if op == "OPR_AND" then
  2098. assert(e1.t == self.NO_JUMP) -- list must be closed
  2099. self:dischargevars(fs, e2)
  2100. e2.f = self:concat(fs, e2.f, e1.f)
  2101. copyexp(e1, e2)
  2102. elseif op == "OPR_OR" then
  2103. assert(e1.f == self.NO_JUMP) -- list must be closed
  2104. self:dischargevars(fs, e2)
  2105. e2.t = self:concat(fs, e2.t, e1.t)
  2106. copyexp(e1, e2)
  2107. elseif op == "OPR_CONCAT" then
  2108. self:exp2val(fs, e2)
  2109. if e2.k == "VRELOCABLE" and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then
  2110. assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1)
  2111. self:freeexp(fs, e1)
  2112. luaP:SETARG_B(self:getcode(fs, e2), e1.info)
  2113. e1.k = "VRELOCABLE"
  2114. e1.info = e2.info
  2115. else
  2116. self:exp2nextreg(fs, e2) -- operand must be on the 'stack'
  2117. self:codearith(fs, "OP_CONCAT", e1, e2)
  2118. end
  2119. else
  2120. -- the following uses a table lookup in place of conditionals
  2121. local arith = self.arith_op[op]
  2122. if arith then
  2123. self:codearith(fs, arith, e1, e2)
  2124. else
  2125. local comp = self.comp_op[op]
  2126. if comp then
  2127. self:codecomp(fs, comp, self.comp_cond[op], e1, e2)
  2128. else
  2129. assert(0)
  2130. end
  2131. end--if arith
  2132. end--if op
  2133. end
  2134.  
  2135. ------------------------------------------------------------------------
  2136. -- adjusts debug information for last instruction written, in order to
  2137. -- change the line where item comes into existence
  2138. -- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat()
  2139. ------------------------------------------------------------------------
  2140. function luaK:fixline(fs, line)
  2141. fs.f.lineinfo[fs.pc - 1] = line
  2142. end
  2143.  
  2144. ------------------------------------------------------------------------
  2145. -- general function to write an instruction into the instruction buffer,
  2146. -- sets debug information too
  2147. -- * used in luaK:codeABC(), luaK:codeABx()
  2148. -- * called directly by (lparser) luaY:whilestat()
  2149. ------------------------------------------------------------------------
  2150. function luaK:code(fs, i, line)
  2151. local f = fs.f
  2152. self:dischargejpc(fs) -- 'pc' will change
  2153. -- put new instruction in code array
  2154. luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil,
  2155. luaY.MAX_INT, "code size overflow")
  2156. f.code[fs.pc] = i
  2157. -- save corresponding line information
  2158. luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil,
  2159. luaY.MAX_INT, "code size overflow")
  2160. f.lineinfo[fs.pc] = line
  2161. local pc = fs.pc
  2162. fs.pc = fs.pc + 1
  2163. return pc
  2164. end
  2165.  
  2166. ------------------------------------------------------------------------
  2167. -- writes an instruction of type ABC
  2168. -- * calls luaK:code()
  2169. ------------------------------------------------------------------------
  2170. function luaK:codeABC(fs, o, a, b, c)
  2171. assert(luaP:getOpMode(o) == luaP.OpMode.iABC)
  2172. assert(luaP:getBMode(o) ~= luaP.OpArgMask.OpArgN or b == 0)
  2173. assert(luaP:getCMode(o) ~= luaP.OpArgMask.OpArgN or c == 0)
  2174. return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline)
  2175. end
  2176.  
  2177. ------------------------------------------------------------------------
  2178. -- writes an instruction of type ABx
  2179. -- * calls luaK:code(), called by luaK:codeAsBx()
  2180. ------------------------------------------------------------------------
  2181. function luaK:codeABx(fs, o, a, bc)
  2182. assert(luaP:getOpMode(o) == luaP.OpMode.iABx or
  2183. luaP:getOpMode(o) == luaP.OpMode.iAsBx)
  2184. assert(luaP:getCMode(o) == luaP.OpArgMask.OpArgN)
  2185. return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline)
  2186. end
  2187.  
  2188. ------------------------------------------------------------------------
  2189. --
  2190. -- * used in (lparser) luaY:closelistfield(), luaY:lastlistfield()
  2191. ------------------------------------------------------------------------
  2192. function luaK:setlist(fs, base, nelems, tostore)
  2193. local c = math.floor((nelems - 1)/luaP.LFIELDS_PER_FLUSH) + 1
  2194. local b = (tostore == luaY.LUA_MULTRET) and 0 or tostore
  2195. assert(tostore ~= 0)
  2196. if c <= luaP.MAXARG_C then
  2197. self:codeABC(fs, "OP_SETLIST", base, b, c)
  2198. else
  2199. self:codeABC(fs, "OP_SETLIST", base, b, 0)
  2200. self:code(fs, luaP:CREATE_Inst(c), fs.ls.lastline)
  2201. end
  2202. fs.freereg = base + 1 -- free registers with list values
  2203. end
  2204.  
  2205. return function(a) luaY = a return luaK end
  2206. end
  2207. luaK=luaK()
  2208. local luaY = function ()
  2209. --requires luaP, luaX, luaK
  2210. local luaY = {}
  2211. local luaX = luaX
  2212. local luaK = luaK(luaY)
  2213. local luaP = luaP
  2214.  
  2215. --[[--------------------------------------------------------------------
  2216. -- Expression descriptor
  2217. -- * expkind changed to string constants; luaY:assignment was the only
  2218. -- function to use a relational operator with this enumeration
  2219. -- VVOID -- no value
  2220. -- VNIL -- no value
  2221. -- VTRUE -- no value
  2222. -- VFALSE -- no value
  2223. -- VK -- info = index of constant in 'k'
  2224. -- VKNUM -- nval = numerical value
  2225. -- VLOCAL -- info = local register
  2226. -- VUPVAL, -- info = index of upvalue in 'upvalues'
  2227. -- VGLOBAL -- info = index of table; aux = index of global name in 'k'
  2228. -- VINDEXED -- info = table register; aux = index register (or 'k')
  2229. -- VJMP -- info = instruction pc
  2230. -- VRELOCABLE -- info = instruction pc
  2231. -- VNONRELOC -- info = result register
  2232. -- VCALL -- info = instruction pc
  2233. -- VVARARG -- info = instruction pc
  2234. } ----------------------------------------------------------------------]]
  2235.  
  2236. --[[--------------------------------------------------------------------
  2237. -- * expdesc in Lua 5.1.x has a union u and another struct s; this Lua
  2238. -- implementation ignores all instances of u and s usage
  2239. -- struct expdesc:
  2240. -- k -- (enum: expkind)
  2241. -- info, aux -- (int, int)
  2242. -- nval -- (lua_Number)
  2243. -- t -- patch list of 'exit when true'
  2244. -- f -- patch list of 'exit when false'
  2245. ----------------------------------------------------------------------]]
  2246.  
  2247. --[[--------------------------------------------------------------------
  2248. -- struct upvaldesc:
  2249. -- k -- (lu_byte)
  2250. -- info -- (lu_byte)
  2251. ----------------------------------------------------------------------]]
  2252.  
  2253. --[[--------------------------------------------------------------------
  2254. -- state needed to generate code for a given function
  2255. -- struct FuncState:
  2256. -- f -- current function header (table: Proto)
  2257. -- h -- table to find (and reuse) elements in 'k' (table: Table)
  2258. -- prev -- enclosing function (table: FuncState)
  2259. -- ls -- lexical state (table: LexState)
  2260. -- L -- copy of the Lua state (table: lua_State)
  2261. -- bl -- chain of current blocks (table: BlockCnt)
  2262. -- pc -- next position to code (equivalent to 'ncode')
  2263. -- lasttarget -- 'pc' of last 'jump target'
  2264. -- jpc -- list of pending jumps to 'pc'
  2265. -- freereg -- first free register
  2266. -- nk -- number of elements in 'k'
  2267. -- np -- number of elements in 'p'
  2268. -- nlocvars -- number of elements in 'locvars'
  2269. -- nactvar -- number of active local variables
  2270. -- upvalues[LUAI_MAXUPVALUES] -- upvalues (table: upvaldesc)
  2271. -- actvar[LUAI_MAXVARS] -- declared-variable stack
  2272. ----------------------------------------------------------------------]]
  2273.  
  2274. ------------------------------------------------------------------------
  2275. -- constants used by parser
  2276. -- * picks up duplicate values from luaX if required
  2277. ------------------------------------------------------------------------
  2278.  
  2279. luaY.LUA_QS = luaX.LUA_QS or "'%s'" -- (from luaconf.h)
  2280.  
  2281. luaY.SHRT_MAX = 32767 -- (from <limits.h>)
  2282. luaY.LUAI_MAXVARS = 200 -- (luaconf.h)
  2283. luaY.LUAI_MAXUPVALUES = 60 -- (luaconf.h)
  2284. luaY.MAX_INT = luaX.MAX_INT or 2147483645 -- (from llimits.h)
  2285. -- * INT_MAX-2 for 32-bit systems
  2286. luaY.LUAI_MAXCCALLS = 200 -- (from luaconf.h)
  2287.  
  2288. luaY.VARARG_HASARG = 1 -- (from lobject.h)
  2289. -- NOTE: HASARG_MASK is value-specific
  2290. luaY.HASARG_MASK = 2 -- this was added for a bitop in parlist()
  2291. luaY.VARARG_ISVARARG = 2
  2292. -- NOTE: there is some value-specific code that involves VARARG_NEEDSARG
  2293. luaY.VARARG_NEEDSARG = 4
  2294.  
  2295. luaY.LUA_MULTRET = -1 -- (lua.h)
  2296.  
  2297. --[[--------------------------------------------------------------------
  2298. -- other functions
  2299. ----------------------------------------------------------------------]]
  2300.  
  2301. ------------------------------------------------------------------------
  2302. -- LUA_QL describes how error messages quote program elements.
  2303. -- CHANGE it if you want a different appearance. (from luaconf.h)
  2304. ------------------------------------------------------------------------
  2305. function luaY:LUA_QL(x)
  2306. return "'"..x.."'"
  2307. end
  2308.  
  2309. ------------------------------------------------------------------------
  2310. -- this is a stripped-down luaM_growvector (from lmem.h) which is a
  2311. -- macro based on luaM_growaux (in lmem.c); all the following does is
  2312. -- reproduce the size limit checking logic of the original function
  2313. -- so that error behaviour is identical; all arguments preserved for
  2314. -- convenience, even those which are unused
  2315. -- * set the t field to nil, since this originally does a sizeof(t)
  2316. -- * size (originally a pointer) is never updated, their final values
  2317. -- are set by luaY:close_func(), so overall things should still work
  2318. ------------------------------------------------------------------------
  2319. function luaY:growvector(L, v, nelems, size, t, limit, e)
  2320. if nelems >= limit then
  2321. error(e) -- was luaG_runerror
  2322. end
  2323. end
  2324.  
  2325. ------------------------------------------------------------------------
  2326. -- initialize a new function prototype structure (from lfunc.c)
  2327. -- * used only in open_func()
  2328. ------------------------------------------------------------------------
  2329. function luaY:newproto(L)
  2330. local f = {} -- Proto
  2331. -- luaC_link(L, obj2gco(f), LUA_TPROTO); /* GC */
  2332. f.k = {}
  2333. f.sizek = 0
  2334. f.p = {}
  2335. f.sizep = 0
  2336. f.code = {}
  2337. f.sizecode = 0
  2338. f.sizelineinfo = 0
  2339. f.sizeupvalues = 0
  2340. f.nups = 0
  2341. f.upvalues = {}
  2342. f.numparams = 0
  2343. f.is_vararg = 0
  2344. f.maxstacksize = 0
  2345. f.lineinfo = {}
  2346. f.sizelocvars = 0
  2347. f.locvars = {}
  2348. f.lineDefined = 0
  2349. f.lastlinedefined = 0
  2350. f.source = nil
  2351. return f
  2352. end
  2353.  
  2354. ------------------------------------------------------------------------
  2355. -- converts an integer to a "floating point byte", represented as
  2356. -- (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
  2357. -- eeeee != 0 and (xxx) otherwise.
  2358. ------------------------------------------------------------------------
  2359. function luaY:int2fb(x)
  2360. local e = 0 -- exponent
  2361. while x >= 16 do
  2362. x = math.floor((x + 1) / 2)
  2363. e = e + 1
  2364. end
  2365. if x < 8 then
  2366. return x
  2367. else
  2368. return ((e + 1) * 8) + (x - 8)
  2369. end
  2370. end
  2371.  
  2372. --[[--------------------------------------------------------------------
  2373. -- parser functions
  2374. ----------------------------------------------------------------------]]
  2375.  
  2376. ------------------------------------------------------------------------
  2377. -- true of the kind of expression produces multiple return values
  2378. ------------------------------------------------------------------------
  2379. function luaY:hasmultret(k)
  2380. return k == "VCALL" or k == "VVARARG"
  2381. end
  2382.  
  2383. ------------------------------------------------------------------------
  2384. -- convenience function to access active local i, returns entry
  2385. ------------------------------------------------------------------------
  2386. function luaY:getlocvar(fs, i)
  2387. return fs.f.locvars[ fs.actvar[i] ]
  2388. end
  2389.  
  2390. ------------------------------------------------------------------------
  2391. -- check a limit, string m provided as an error message
  2392. ------------------------------------------------------------------------
  2393. function luaY:checklimit(fs, v, l, m)
  2394. if v > l then self:errorlimit(fs, l, m) end
  2395. end
  2396.  
  2397. --[[--------------------------------------------------------------------
  2398. -- nodes for block list (list of active blocks)
  2399. -- struct BlockCnt:
  2400. -- previous -- chain (table: BlockCnt)
  2401. -- breaklist -- list of jumps out of this loop
  2402. -- nactvar -- # active local variables outside the breakable structure
  2403. -- upval -- true if some variable in the block is an upvalue (boolean)
  2404. -- isbreakable -- true if 'block' is a loop (boolean)
  2405. ----------------------------------------------------------------------]]
  2406.  
  2407. ------------------------------------------------------------------------
  2408. -- prototypes for recursive non-terminal functions
  2409. ------------------------------------------------------------------------
  2410. -- prototypes deleted; not required in Lua
  2411.  
  2412. ------------------------------------------------------------------------
  2413. -- reanchor if last token is has a constant string, see close_func()
  2414. -- * used only in close_func()
  2415. ------------------------------------------------------------------------
  2416. function luaY:anchor_token(ls)
  2417. if ls.t.token == "TK_NAME" or ls.t.token == "TK_STRING" then
  2418. -- not relevant to Lua implementation of parser
  2419. -- local ts = ls.t.seminfo
  2420. -- luaX_newstring(ls, getstr(ts), ts->tsv.len); /* C */
  2421. end
  2422. end
  2423.  
  2424. ------------------------------------------------------------------------
  2425. -- throws a syntax error if token expected is not there
  2426. ------------------------------------------------------------------------
  2427. function luaY:error_expected(ls, token)
  2428. luaX:syntaxerror(ls,
  2429. string.format(self.LUA_QS.." expected", luaX:token2str(ls, token)))
  2430. end
  2431.  
  2432. ------------------------------------------------------------------------
  2433. -- prepares error message for display, for limits exceeded
  2434. -- * used only in checklimit()
  2435. ------------------------------------------------------------------------
  2436. function luaY:errorlimit(fs, limit, what)
  2437. local msg = (fs.f.linedefined == 0) and
  2438. string.format("main function has more than %d %s", limit, what) or
  2439. string.format("function at line %d has more than %d %s",
  2440. fs.f.linedefined, limit, what)
  2441. luaX:lexerror(fs.ls, msg, 0)
  2442. end
  2443.  
  2444. ------------------------------------------------------------------------
  2445. -- tests for a token, returns outcome
  2446. -- * return value changed to boolean
  2447. ------------------------------------------------------------------------
  2448. function luaY:testnext(ls, c)
  2449. if ls.t.token == c then
  2450. luaX:next(ls)
  2451. return true
  2452. else
  2453. return false
  2454. end
  2455. end
  2456.  
  2457. ------------------------------------------------------------------------
  2458. -- check for existence of a token, throws error if not found
  2459. ------------------------------------------------------------------------
  2460. function luaY:check(ls, c)
  2461. if ls.t.token ~= c then
  2462. self:error_expected(ls, c)
  2463. end
  2464. end
  2465.  
  2466. ------------------------------------------------------------------------
  2467. -- verify existence of a token, then skip it
  2468. ------------------------------------------------------------------------
  2469. function luaY:checknext(ls, c)
  2470. self:check(ls, c)
  2471. luaX:next(ls)
  2472. end
  2473.  
  2474. ------------------------------------------------------------------------
  2475. -- throws error if condition not matched
  2476. ------------------------------------------------------------------------
  2477. function luaY:check_condition(ls, c, msg)
  2478. if not c then luaX:syntaxerror(ls, msg) end
  2479. end
  2480.  
  2481. ------------------------------------------------------------------------
  2482. -- verifies token conditions are met or else throw error
  2483. ------------------------------------------------------------------------
  2484. function luaY:check_match(ls, what, who, where)
  2485. if not self:testnext(ls, what) then
  2486. if where == ls.linenumber then
  2487. self:error_expected(ls, what)
  2488. else
  2489. luaX:syntaxerror(ls, string.format(
  2490. self.LUA_QS.." expected (to close "..self.LUA_QS.." at line %d)",
  2491. luaX:token2str(ls, what), luaX:token2str(ls, who), where))
  2492. end
  2493. end
  2494. end
  2495.  
  2496. ------------------------------------------------------------------------
  2497. -- expect that token is a name, return the name
  2498. ------------------------------------------------------------------------
  2499. function luaY:str_checkname(ls)
  2500. self:check(ls, "TK_NAME")
  2501. local ts = ls.t.seminfo
  2502. luaX:next(ls)
  2503. return ts
  2504. end
  2505.  
  2506. ------------------------------------------------------------------------
  2507. -- initialize a struct expdesc, expression description data structure
  2508. ------------------------------------------------------------------------
  2509. function luaY:init_exp(e, k, i)
  2510. e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP
  2511. e.k = k
  2512. e.info = i
  2513. end
  2514.  
  2515. ------------------------------------------------------------------------
  2516. -- adds given string s in string pool, sets e as VK
  2517. ------------------------------------------------------------------------
  2518. function luaY:codestring(ls, e, s)
  2519. self:init_exp(e, "VK", luaK:stringK(ls.fs, s))
  2520. end
  2521.  
  2522. ------------------------------------------------------------------------
  2523. -- consume a name token, adds it to string pool, sets e as VK
  2524. ------------------------------------------------------------------------
  2525. function luaY:checkname(ls, e)
  2526. self:codestring(ls, e, self:str_checkname(ls))
  2527. end
  2528.  
  2529. ------------------------------------------------------------------------
  2530. -- creates struct entry for a local variable
  2531. -- * used only in new_localvar()
  2532. ------------------------------------------------------------------------
  2533. function luaY:registerlocalvar(ls, varname)
  2534. local fs = ls.fs
  2535. local f = fs.f
  2536. self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars,
  2537. nil, self.SHRT_MAX, "too many local variables")
  2538. -- loop to initialize empty f.locvar positions not required
  2539. f.locvars[fs.nlocvars] = {} -- LocVar
  2540. f.locvars[fs.nlocvars].varname = varname
  2541. -- luaC_objbarrier(ls.L, f, varname) /* GC */
  2542. local nlocvars = fs.nlocvars
  2543. fs.nlocvars = fs.nlocvars + 1
  2544. return nlocvars
  2545. end
  2546.  
  2547. ------------------------------------------------------------------------
  2548. -- creates a new local variable given a name and an offset from nactvar
  2549. -- * used in fornum(), forlist(), parlist(), body()
  2550. ------------------------------------------------------------------------
  2551. function luaY:new_localvarliteral(ls, v, n)
  2552. self:new_localvar(ls, v, n)
  2553. end
  2554.  
  2555. ------------------------------------------------------------------------
  2556. -- register a local variable, set in active variable list
  2557. ------------------------------------------------------------------------
  2558. function luaY:new_localvar(ls, name, n)
  2559. local fs = ls.fs
  2560. self:checklimit(fs, fs.nactvar + n + 1, self.LUAI_MAXVARS, "local variables")
  2561. fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name)
  2562. end
  2563.  
  2564. ------------------------------------------------------------------------
  2565. -- adds nvars number of new local variables, set debug information
  2566. ------------------------------------------------------------------------
  2567. function luaY:adjustlocalvars(ls, nvars)
  2568. local fs = ls.fs
  2569. fs.nactvar = fs.nactvar + nvars
  2570. for i = nvars, 1, -1 do
  2571. self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc
  2572. end
  2573. end
  2574.  
  2575. ------------------------------------------------------------------------
  2576. -- removes a number of locals, set debug information
  2577. ------------------------------------------------------------------------
  2578. function luaY:removevars(ls, tolevel)
  2579. local fs = ls.fs
  2580. while fs.nactvar > tolevel do
  2581. fs.nactvar = fs.nactvar - 1
  2582. self:getlocvar(fs, fs.nactvar).endpc = fs.pc
  2583. end
  2584. end
  2585.  
  2586. ------------------------------------------------------------------------
  2587. -- returns an existing upvalue index based on the given name, or
  2588. -- creates a new upvalue struct entry and returns the new index
  2589. -- * used only in singlevaraux()
  2590. ------------------------------------------------------------------------
  2591. function luaY:indexupvalue(fs, name, v)
  2592. local f = fs.f
  2593. for i = 0, f.nups - 1 do
  2594. if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then
  2595. assert(f.upvalues[i] == name)
  2596. return i
  2597. end
  2598. end
  2599. -- new one
  2600. self:checklimit(fs, f.nups + 1, self.LUAI_MAXUPVALUES, "upvalues")
  2601. self:growvector(fs.L, f.upvalues, f.nups, f.sizeupvalues,
  2602. nil, self.MAX_INT, "")
  2603. -- loop to initialize empty f.upvalues positions not required
  2604. f.upvalues[f.nups] = name
  2605. -- luaC_objbarrier(fs->L, f, name); /* GC */
  2606. assert(v.k == "VLOCAL" or v.k == "VUPVAL")
  2607. -- this is a partial copy; only k & info fields used
  2608. fs.upvalues[f.nups] = { k = v.k, info = v.info }
  2609. local nups = f.nups
  2610. f.nups = f.nups + 1
  2611. return nups
  2612. end
  2613.  
  2614. ------------------------------------------------------------------------
  2615. -- search the local variable namespace of the given fs for a match
  2616. -- * used only in singlevaraux()
  2617. ------------------------------------------------------------------------
  2618. function luaY:searchvar(fs, n)
  2619. for i = fs.nactvar - 1, 0, -1 do
  2620. if n == self:getlocvar(fs, i).varname then
  2621. return i
  2622. end
  2623. end
  2624. return -1 -- not found
  2625. end
  2626.  
  2627. ------------------------------------------------------------------------
  2628. -- * mark upvalue flags in function states up to a given level
  2629. -- * used only in singlevaraux()
  2630. ------------------------------------------------------------------------
  2631. function luaY:markupval(fs, level)
  2632. local bl = fs.bl
  2633. while bl and bl.nactvar > level do bl = bl.previous end
  2634. if bl then bl.upval = true end
  2635. end
  2636.  
  2637. ------------------------------------------------------------------------
  2638. -- handle locals, globals and upvalues and related processing
  2639. -- * search mechanism is recursive, calls itself to search parents
  2640. -- * used only in singlevar()
  2641. ------------------------------------------------------------------------
  2642. function luaY:singlevaraux(fs, n, var, base)
  2643. if fs == nil then -- no more levels?
  2644. self:init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable
  2645. return "VGLOBAL"
  2646. else
  2647. local v = self:searchvar(fs, n) -- look up at current level
  2648. if v >= 0 then
  2649. self:init_exp(var, "VLOCAL", v)
  2650. if base == 0 then
  2651. self:markupval(fs, v) -- local will be used as an upval
  2652. end
  2653. return "VLOCAL"
  2654. else -- not found at current level; try upper one
  2655. if self:singlevaraux(fs.prev, n, var, 0) == "VGLOBAL" then
  2656. return "VGLOBAL"
  2657. end
  2658. var.info = self:indexupvalue(fs, n, var) -- else was LOCAL or UPVAL
  2659. var.k = "VUPVAL" -- upvalue in this level
  2660. return "VUPVAL"
  2661. end--if v
  2662. end--if fs
  2663. end
  2664.  
  2665. ------------------------------------------------------------------------
  2666. -- consume a name token, creates a variable (global|local|upvalue)
  2667. -- * used in prefixexp(), funcname()
  2668. ------------------------------------------------------------------------
  2669. function luaY:singlevar(ls, var)
  2670. local varname = self:str_checkname(ls)
  2671. local fs = ls.fs
  2672. if self:singlevaraux(fs, varname, var, 1) == "VGLOBAL" then
  2673. var.info = luaK:stringK(fs, varname) -- info points to global name
  2674. end
  2675. end
  2676.  
  2677. ------------------------------------------------------------------------
  2678. -- adjust RHS to match LHS in an assignment
  2679. -- * used in assignment(), forlist(), localstat()
  2680. ------------------------------------------------------------------------
  2681. function luaY:adjust_assign(ls, nvars, nexps, e)
  2682. local fs = ls.fs
  2683. local extra = nvars - nexps
  2684. if self:hasmultret(e.k) then
  2685. extra = extra + 1 -- includes call itself
  2686. if extra <= 0 then extra = 0 end
  2687. luaK:setreturns(fs, e, extra) -- last exp. provides the difference
  2688. if extra > 1 then luaK:reserveregs(fs, extra - 1) end
  2689. else
  2690. if e.k ~= "VVOID" then luaK:exp2nextreg(fs, e) end -- close last expression
  2691. if extra > 0 then
  2692. local reg = fs.freereg
  2693. luaK:reserveregs(fs, extra)
  2694. luaK:_nil(fs, reg, extra)
  2695. end
  2696. end
  2697. end
  2698.  
  2699. ------------------------------------------------------------------------
  2700. -- tracks and limits parsing depth, assert check at end of parsing
  2701. ------------------------------------------------------------------------
  2702. function luaY:enterlevel(ls)
  2703. ls.L.nCcalls = ls.L.nCcalls + 1
  2704. if ls.L.nCcalls > self.LUAI_MAXCCALLS then
  2705. luaX:lexerror(ls, "chunk has too many syntax levels", 0)
  2706. end
  2707. end
  2708.  
  2709. ------------------------------------------------------------------------
  2710. -- tracks parsing depth, a pair with luaY:enterlevel()
  2711. ------------------------------------------------------------------------
  2712. function luaY:leavelevel(ls)
  2713. ls.L.nCcalls = ls.L.nCcalls - 1
  2714. end
  2715.  
  2716. ------------------------------------------------------------------------
  2717. -- enters a code unit, initializes elements
  2718. ------------------------------------------------------------------------
  2719. function luaY:enterblock(fs, bl, isbreakable)
  2720. bl.breaklist = luaK.NO_JUMP
  2721. bl.isbreakable = isbreakable
  2722. bl.nactvar = fs.nactvar
  2723. bl.upval = false
  2724. bl.previous = fs.bl
  2725. fs.bl = bl
  2726. assert(fs.freereg == fs.nactvar)
  2727. end
  2728.  
  2729. ------------------------------------------------------------------------
  2730. -- leaves a code unit, close any upvalues
  2731. ------------------------------------------------------------------------
  2732. function luaY:leaveblock(fs)
  2733. local bl = fs.bl
  2734. fs.bl = bl.previous
  2735. self:removevars(fs.ls, bl.nactvar)
  2736. if bl.upval then
  2737. luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
  2738. end
  2739. -- a block either controls scope or breaks (never both)
  2740. assert(not bl.isbreakable or not bl.upval)
  2741. assert(bl.nactvar == fs.nactvar)
  2742. fs.freereg = fs.nactvar -- free registers
  2743. luaK:patchtohere(fs, bl.breaklist)
  2744. end
  2745.  
  2746. ------------------------------------------------------------------------
  2747. -- implement the instantiation of a function prototype, append list of
  2748. -- upvalues after the instantiation instruction
  2749. -- * used only in body()
  2750. ------------------------------------------------------------------------
  2751. function luaY:pushclosure(ls, func, v)
  2752. local fs = ls.fs
  2753. local f = fs.f
  2754. self:growvector(ls.L, f.p, fs.np, f.sizep, nil,
  2755. luaP.MAXARG_Bx, "constant table overflow")
  2756. -- loop to initialize empty f.p positions not required
  2757. f.p[fs.np] = func.f
  2758. fs.np = fs.np + 1
  2759. -- luaC_objbarrier(ls->L, f, func->f); /* C */
  2760. self:init_exp(v, "VRELOCABLE", luaK:codeABx(fs, "OP_CLOSURE", 0, fs.np - 1))
  2761. for i = 0, func.f.nups - 1 do
  2762. local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL"
  2763. luaK:codeABC(fs, o, 0, func.upvalues[i].info, 0)
  2764. end
  2765. end
  2766.  
  2767. ------------------------------------------------------------------------
  2768. -- opening of a function
  2769. ------------------------------------------------------------------------
  2770. function luaY:open_func(ls, fs)
  2771. local L = ls.L
  2772. local f = self:newproto(ls.L)
  2773. fs.f = f
  2774. fs.prev = ls.fs -- linked list of funcstates
  2775. fs.ls = ls
  2776. fs.L = L
  2777. ls.fs = fs
  2778. fs.pc = 0
  2779. fs.lasttarget = -1
  2780. fs.jpc = luaK.NO_JUMP
  2781. fs.freereg = 0
  2782. fs.nk = 0
  2783. fs.np = 0
  2784. fs.nlocvars = 0
  2785. fs.nactvar = 0
  2786. fs.bl = nil
  2787. f.source = ls.source
  2788. f.maxstacksize = 2 -- registers 0/1 are always valid
  2789. fs.h = {} -- constant table; was luaH_new call
  2790. -- anchor table of constants and prototype (to avoid being collected)
  2791. -- sethvalue2s(L, L->top, fs->h); incr_top(L); /* C */
  2792. -- setptvalue2s(L, L->top, f); incr_top(L);
  2793. end
  2794.  
  2795. ------------------------------------------------------------------------
  2796. -- closing of a function
  2797. ------------------------------------------------------------------------
  2798. function luaY:close_func(ls)
  2799. local L = ls.L
  2800. local fs = ls.fs
  2801. local f = fs.f
  2802. self:removevars(ls, 0)
  2803. luaK:ret(fs, 0, 0) -- final return
  2804. -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p,
  2805. -- f->locvars, f->upvalues; not required for Lua table arrays
  2806. f.sizecode = fs.pc
  2807. f.sizelineinfo = fs.pc
  2808. f.sizek = fs.nk
  2809. f.sizep = fs.np
  2810. f.sizelocvars = fs.nlocvars
  2811. f.sizeupvalues = f.nups
  2812. --assert(luaG_checkcode(f)) -- currently not implemented
  2813. assert(fs.bl == nil)
  2814. ls.fs = fs.prev
  2815. -- the following is not required for this implementation; kept here
  2816. -- for completeness
  2817. -- L->top -= 2; /* remove table and prototype from the stack */
  2818. -- last token read was anchored in defunct function; must reanchor it
  2819. if fs then self:anchor_token(ls) end
  2820. end
  2821.  
  2822. ------------------------------------------------------------------------
  2823. -- parser initialization function
  2824. -- * note additional sub-tables needed for LexState, FuncState
  2825. ------------------------------------------------------------------------
  2826. function luaY:parser(L, z, buff, name)
  2827. local lexstate = {} -- LexState
  2828. lexstate.t = {}
  2829. lexstate.lookahead = {}
  2830. local funcstate = {} -- FuncState
  2831. funcstate.upvalues = {}
  2832. funcstate.actvar = {}
  2833. -- the following nCcalls initialization added for convenience
  2834. L.nCcalls = 0
  2835. lexstate.buff = buff
  2836. luaX:setinput(L, lexstate, z, name)
  2837. self:open_func(lexstate, funcstate)
  2838. funcstate.f.is_vararg = self.VARARG_ISVARARG -- main func. is always vararg
  2839. luaX:next(lexstate) -- read first token
  2840. self:chunk(lexstate)
  2841. self:check(lexstate, "TK_EOS")
  2842. self:close_func(lexstate)
  2843. assert(funcstate.prev == nil)
  2844. assert(funcstate.f.nups == 0)
  2845. assert(lexstate.fs == nil)
  2846. return funcstate.f
  2847. end
  2848.  
  2849. --[[--------------------------------------------------------------------
  2850. -- GRAMMAR RULES
  2851. ----------------------------------------------------------------------]]
  2852.  
  2853. ------------------------------------------------------------------------
  2854. -- parse a function name suffix, for function call specifications
  2855. -- * used in primaryexp(), funcname()
  2856. ------------------------------------------------------------------------
  2857. function luaY:field(ls, v)
  2858. -- field -> ['.' | ':'] NAME
  2859. local fs = ls.fs
  2860. local key = {} -- expdesc
  2861. luaK:exp2anyreg(fs, v)
  2862. luaX:next(ls) -- skip the dot or colon
  2863. self:checkname(ls, key)
  2864. luaK:indexed(fs, v, key)
  2865. end
  2866.  
  2867. ------------------------------------------------------------------------
  2868. -- parse a table indexing suffix, for constructors, expressions
  2869. -- * used in recfield(), primaryexp()
  2870. ------------------------------------------------------------------------
  2871. function luaY:yindex(ls, v)
  2872. -- index -> '[' expr ']'
  2873. luaX:next(ls) -- skip the '['
  2874. self:expr(ls, v)
  2875. luaK:exp2val(ls.fs, v)
  2876. self:checknext(ls, "]")
  2877. end
  2878.  
  2879. --[[--------------------------------------------------------------------
  2880. -- Rules for Constructors
  2881. ----------------------------------------------------------------------]]
  2882.  
  2883. --[[--------------------------------------------------------------------
  2884. -- struct ConsControl:
  2885. -- v -- last list item read (table: struct expdesc)
  2886. -- t -- table descriptor (table: struct expdesc)
  2887. -- nh -- total number of 'record' elements
  2888. -- na -- total number of array elements
  2889. -- tostore -- number of array elements pending to be stored
  2890. ----------------------------------------------------------------------]]
  2891.  
  2892. ------------------------------------------------------------------------
  2893. -- parse a table record (hash) field
  2894. -- * used in constructor()
  2895. ------------------------------------------------------------------------
  2896. function luaY:recfield(ls, cc)
  2897. -- recfield -> (NAME | '['exp1']') = exp1
  2898. local fs = ls.fs
  2899. local reg = ls.fs.freereg
  2900. local key, val = {}, {} -- expdesc
  2901. if ls.t.token == "TK_NAME" then
  2902. self:checklimit(fs, cc.nh, self.MAX_INT, "items in a constructor")
  2903. self:checkname(ls, key)
  2904. else -- ls->t.token == '['
  2905. self:yindex(ls, key)
  2906. end
  2907. cc.nh = cc.nh + 1
  2908. self:checknext(ls, "=")
  2909. local rkkey = luaK:exp2RK(fs, key)
  2910. self:expr(ls, val)
  2911. luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, rkkey, luaK:exp2RK(fs, val))
  2912. fs.freereg = reg -- free registers
  2913. end
  2914.  
  2915. ------------------------------------------------------------------------
  2916. -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH)
  2917. -- * used in constructor()
  2918. ------------------------------------------------------------------------
  2919. function luaY:closelistfield(fs, cc)
  2920. if cc.v.k == "VVOID" then return end -- there is no list item
  2921. luaK:exp2nextreg(fs, cc.v)
  2922. cc.v.k = "VVOID"
  2923. if cc.tostore == luaP.LFIELDS_PER_FLUSH then
  2924. luaK:setlist(fs, cc.t.info, cc.na, cc.tostore) -- flush
  2925. cc.tostore = 0 -- no more items pending
  2926. end
  2927. end
  2928.  
  2929. ------------------------------------------------------------------------
  2930. -- emit a set list instruction at the end of parsing list constructor
  2931. -- * used in constructor()
  2932. ------------------------------------------------------------------------
  2933. function luaY:lastlistfield(fs, cc)
  2934. if cc.tostore == 0 then return end
  2935. if self:hasmultret(cc.v.k) then
  2936. luaK:setmultret(fs, cc.v)
  2937. luaK:setlist(fs, cc.t.info, cc.na, self.LUA_MULTRET)
  2938. cc.na = cc.na - 1 -- do not count last expression (unknown number of elements)
  2939. else
  2940. if cc.v.k ~= "VVOID" then
  2941. luaK:exp2nextreg(fs, cc.v)
  2942. end
  2943. luaK:setlist(fs, cc.t.info, cc.na, cc.tostore)
  2944. end
  2945. end
  2946.  
  2947. ------------------------------------------------------------------------
  2948. -- parse a table list (array) field
  2949. -- * used in constructor()
  2950. ------------------------------------------------------------------------
  2951. function luaY:listfield(ls, cc)
  2952. self:expr(ls, cc.v)
  2953. self:checklimit(ls.fs, cc.na, self.MAX_INT, "items in a constructor")
  2954. cc.na = cc.na + 1
  2955. cc.tostore = cc.tostore + 1
  2956. end
  2957.  
  2958. ------------------------------------------------------------------------
  2959. -- parse a table constructor
  2960. -- * used in funcargs(), simpleexp()
  2961. ------------------------------------------------------------------------
  2962. function luaY:constructor(ls, t)
  2963. -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}'
  2964. -- field -> recfield | listfield
  2965. -- fieldsep -> ',' | ';'
  2966. local fs = ls.fs
  2967. local line = ls.linenumber
  2968. local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0)
  2969. local cc = {} -- ConsControl
  2970. cc.v = {}
  2971. cc.na, cc.nh, cc.tostore = 0, 0, 0
  2972. cc.t = t
  2973. self:init_exp(t, "VRELOCABLE", pc)
  2974. self:init_exp(cc.v, "VVOID", 0) -- no value (yet)
  2975. luaK:exp2nextreg(ls.fs, t) -- fix it at stack top (for gc)
  2976. self:checknext(ls, "{")
  2977. repeat
  2978. assert(cc.v.k == "VVOID" or cc.tostore > 0)
  2979. if ls.t.token == "}" then break end
  2980. self:closelistfield(fs, cc)
  2981. local c = ls.t.token
  2982.  
  2983. if c == "TK_NAME" then -- may be listfields or recfields
  2984. luaX:lookahead(ls)
  2985. if ls.lookahead.token ~= "=" then -- expression?
  2986. self:listfield(ls, cc)
  2987. else
  2988. self:recfield(ls, cc)
  2989. end
  2990. elseif c == "[" then -- constructor_item -> recfield
  2991. self:recfield(ls, cc)
  2992. else -- constructor_part -> listfield
  2993. self:listfield(ls, cc)
  2994. end
  2995. until not self:testnext(ls, ",") and not self:testnext(ls, ";")
  2996. self:check_match(ls, "}", "{", line)
  2997. self:lastlistfield(fs, cc)
  2998. luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size
  2999. luaP:SETARG_C(fs.f.code[pc], self:int2fb(cc.nh)) -- set initial table size
  3000. end
  3001.  
  3002. -- }======================================================================
  3003.  
  3004. ------------------------------------------------------------------------
  3005. -- parse the arguments (parameters) of a function declaration
  3006. -- * used in body()
  3007. ------------------------------------------------------------------------
  3008. function luaY:parlist(ls)
  3009. -- parlist -> [ param { ',' param } ]
  3010. local fs = ls.fs
  3011. local f = fs.f
  3012. local nparams = 0
  3013. f.is_vararg = 0
  3014. if ls.t.token ~= ")" then -- is 'parlist' not empty?
  3015. repeat
  3016. local c = ls.t.token
  3017. if c == "TK_NAME" then -- param -> NAME
  3018. self:new_localvar(ls, self:str_checkname(ls), nparams)
  3019. nparams = nparams + 1
  3020. elseif c == "TK_DOTS" then -- param -> `...'
  3021. luaX:next(ls)
  3022. -- [[
  3023. -- #if defined(LUA_COMPAT_VARARG)
  3024. -- use `arg' as default name
  3025. self:new_localvarliteral(ls, "arg", nparams)
  3026. nparams = nparams + 1
  3027. f.is_vararg = self.VARARG_HASARG + self.VARARG_NEEDSARG
  3028. -- #endif
  3029. --]]
  3030. f.is_vararg = f.is_vararg + self.VARARG_ISVARARG
  3031. else
  3032. luaX:syntaxerror(ls, "<name> or "..self:LUA_QL("...").." expected")
  3033. end
  3034. until f.is_vararg ~= 0 or not self:testnext(ls, ",")
  3035. end--if
  3036. self:adjustlocalvars(ls, nparams)
  3037. -- NOTE: the following works only when HASARG_MASK is 2!
  3038. f.numparams = fs.nactvar - (f.is_vararg % self.HASARG_MASK)
  3039. luaK:reserveregs(fs, fs.nactvar) -- reserve register for parameters
  3040. end
  3041.  
  3042. ------------------------------------------------------------------------
  3043. -- parse function declaration body
  3044. -- * used in simpleexp(), localfunc(), funcstat()
  3045. ------------------------------------------------------------------------
  3046. function luaY:body(ls, e, needself, line)
  3047. -- body -> '(' parlist ')' chunk END
  3048. local new_fs = {} -- FuncState
  3049. new_fs.upvalues = {}
  3050. new_fs.actvar = {}
  3051. self:open_func(ls, new_fs)
  3052. new_fs.f.lineDefined = line
  3053. self:checknext(ls, "(")
  3054. if needself then
  3055. self:new_localvarliteral(ls, "self", 0)
  3056. self:adjustlocalvars(ls, 1)
  3057. end
  3058. self:parlist(ls)
  3059. self:checknext(ls, ")")
  3060. self:chunk(ls)
  3061. new_fs.f.lastlinedefined = ls.linenumber
  3062. self:check_match(ls, "TK_END", "TK_FUNCTION", line)
  3063. self:close_func(ls)
  3064. self:pushclosure(ls, new_fs, e)
  3065. end
  3066.  
  3067. ------------------------------------------------------------------------
  3068. -- parse a list of comma-separated expressions
  3069. -- * used is multiple locations
  3070. ------------------------------------------------------------------------
  3071. function luaY:explist1(ls, v)
  3072. -- explist1 -> expr { ',' expr }
  3073. local n = 1 -- at least one expression
  3074. self:expr(ls, v)
  3075. while self:testnext(ls, ",") do
  3076. luaK:exp2nextreg(ls.fs, v)
  3077. self:expr(ls, v)
  3078. n = n + 1
  3079. end
  3080. return n
  3081. end
  3082.  
  3083. ------------------------------------------------------------------------
  3084. -- parse the parameters of a function call
  3085. -- * contrast with parlist(), used in function declarations
  3086. -- * used in primaryexp()
  3087. ------------------------------------------------------------------------
  3088. function luaY:funcargs(ls, f)
  3089. local fs = ls.fs
  3090. local args = {} -- expdesc
  3091. local nparams
  3092. local line = ls.linenumber
  3093. local c = ls.t.token
  3094. if c == "(" then -- funcargs -> '(' [ explist1 ] ')'
  3095. if line ~= ls.lastline then
  3096. luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)")
  3097. end
  3098. luaX:next(ls)
  3099. if ls.t.token == ")" then -- arg list is empty?
  3100. args.k = "VVOID"
  3101. else
  3102. self:explist1(ls, args)
  3103. luaK:setmultret(fs, args)
  3104. end
  3105. self:check_match(ls, ")", "(", line)
  3106. elseif c == "{" then -- funcargs -> constructor
  3107. self:constructor(ls, args)
  3108. elseif c == "TK_STRING" then -- funcargs -> STRING
  3109. self:codestring(ls, args, ls.t.seminfo)
  3110. luaX:next(ls) -- must use 'seminfo' before 'next'
  3111. else
  3112. luaX:syntaxerror(ls, "function arguments expected")
  3113. return
  3114. end
  3115. assert(f.k == "VNONRELOC")
  3116. local base = f.info -- base register for call
  3117. if self:hasmultret(args.k) then
  3118. nparams = self.LUA_MULTRET -- open call
  3119. else
  3120. if args.k ~= "VVOID" then
  3121. luaK:exp2nextreg(fs, args) -- close last argument
  3122. end
  3123. nparams = fs.freereg - (base + 1)
  3124. end
  3125. self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2))
  3126. luaK:fixline(fs, line)
  3127. fs.freereg = base + 1 -- call remove function and arguments and leaves
  3128. -- (unless changed) one result
  3129. end
  3130.  
  3131. --[[--------------------------------------------------------------------
  3132. -- Expression parsing
  3133. ----------------------------------------------------------------------]]
  3134.  
  3135. ------------------------------------------------------------------------
  3136. -- parses an expression in parentheses or a single variable
  3137. -- * used in primaryexp()
  3138. ------------------------------------------------------------------------
  3139. function luaY:prefixexp(ls, v)
  3140. -- prefixexp -> NAME | '(' expr ')'
  3141. local c = ls.t.token
  3142. if c == "(" then
  3143. local line = ls.linenumber
  3144. luaX:next(ls)
  3145. self:expr(ls, v)
  3146. self:check_match(ls, ")", "(", line)
  3147. luaK:dischargevars(ls.fs, v)
  3148. elseif c == "TK_NAME" then
  3149. self:singlevar(ls, v)
  3150. else
  3151. luaX:syntaxerror(ls, "unexpected symbol")
  3152. end--if c
  3153. return
  3154. end
  3155.  
  3156. ------------------------------------------------------------------------
  3157. -- parses a prefixexp (an expression in parentheses or a single variable)
  3158. -- or a function call specification
  3159. -- * used in simpleexp(), assignment(), exprstat()
  3160. ------------------------------------------------------------------------
  3161. function luaY:primaryexp(ls, v)
  3162. -- primaryexp ->
  3163. -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs }
  3164. local fs = ls.fs
  3165. self:prefixexp(ls, v)
  3166. while true do
  3167. local c = ls.t.token
  3168. if c == "." then -- field
  3169. self:field(ls, v)
  3170. elseif c == "[" then -- '[' exp1 ']'
  3171. local key = {} -- expdesc
  3172. luaK:exp2anyreg(fs, v)
  3173. self:yindex(ls, key)
  3174. luaK:indexed(fs, v, key)
  3175. elseif c == ":" then -- ':' NAME funcargs
  3176. local key = {} -- expdesc
  3177. luaX:next(ls)
  3178. self:checkname(ls, key)
  3179. luaK:_self(fs, v, key)
  3180. self:funcargs(ls, v)
  3181. elseif c == "(" or c == "TK_STRING" or c == "{" then -- funcargs
  3182. luaK:exp2nextreg(fs, v)
  3183. self:funcargs(ls, v)
  3184. else
  3185. return
  3186. end--if c
  3187. end--while
  3188. end
  3189.  
  3190. ------------------------------------------------------------------------
  3191. -- parses general expression types, constants handled here
  3192. -- * used in subexpr()
  3193. ------------------------------------------------------------------------
  3194. function luaY:simpleexp(ls, v)
  3195. -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
  3196. -- constructor | FUNCTION body | primaryexp
  3197. local c = ls.t.token
  3198. if c == "TK_NUMBER" then
  3199. self:init_exp(v, "VKNUM", 0)
  3200. v.nval = ls.t.seminfo
  3201. elseif c == "TK_STRING" then
  3202. self:codestring(ls, v, ls.t.seminfo)
  3203. elseif c == "TK_NIL" then
  3204. self:init_exp(v, "VNIL", 0)
  3205. elseif c == "TK_TRUE" then
  3206. self:init_exp(v, "VTRUE", 0)
  3207. elseif c == "TK_FALSE" then
  3208. self:init_exp(v, "VFALSE", 0)
  3209. elseif c == "TK_DOTS" then -- vararg
  3210. local fs = ls.fs
  3211. self:check_condition(ls, fs.f.is_vararg ~= 0,
  3212. "cannot use "..self:LUA_QL("...").." outside a vararg function");
  3213. -- NOTE: the following substitutes for a bitop, but is value-specific
  3214. local is_vararg = fs.f.is_vararg
  3215. if is_vararg >= self.VARARG_NEEDSARG then
  3216. fs.f.is_vararg = is_vararg - self.VARARG_NEEDSARG -- don't need 'arg'
  3217. end
  3218. self:init_exp(v, "VVARARG", luaK:codeABC(fs, "OP_VARARG", 0, 1, 0))
  3219. elseif c == "{" then -- constructor
  3220. self:constructor(ls, v)
  3221. return
  3222. elseif c == "TK_FUNCTION" then
  3223. luaX:next(ls)
  3224. self:body(ls, v, false, ls.linenumber)
  3225. return
  3226. else
  3227. self:primaryexp(ls, v)
  3228. return
  3229. end--if c
  3230. luaX:next(ls)
  3231. end
  3232.  
  3233. ------------------------------------------------------------------------
  3234. -- Translates unary operators tokens if found, otherwise returns
  3235. -- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr().
  3236. -- * used in subexpr()
  3237. ------------------------------------------------------------------------
  3238. function luaY:getunopr(op)
  3239. if op == "TK_NOT" then
  3240. return "OPR_NOT"
  3241. elseif op == "-" then
  3242. return "OPR_MINUS"
  3243. elseif op == "#" then
  3244. return "OPR_LEN"
  3245. else
  3246. return "OPR_NOUNOPR"
  3247. end
  3248. end
  3249.  
  3250. ------------------------------------------------------------------------
  3251. -- Translates binary operator tokens if found, otherwise returns
  3252. -- OPR_NOBINOPR. Code generation uses OPR_* style tokens.
  3253. -- * used in subexpr()
  3254. ------------------------------------------------------------------------
  3255. luaY.getbinopr_table = {
  3256. ["+"] = "OPR_ADD",
  3257. ["-"] = "OPR_SUB",
  3258. ["*"] = "OPR_MUL",
  3259. ["/"] = "OPR_DIV",
  3260. ["%"] = "OPR_MOD",
  3261. ["^"] = "OPR_POW",
  3262. ["TK_CONCAT"] = "OPR_CONCAT",
  3263. ["TK_NE"] = "OPR_NE",
  3264. ["TK_EQ"] = "OPR_EQ",
  3265. ["<"] = "OPR_LT",
  3266. ["TK_LE"] = "OPR_LE",
  3267. [">"] = "OPR_GT",
  3268. ["TK_GE"] = "OPR_GE",
  3269. ["TK_AND"] = "OPR_AND",
  3270. ["TK_OR"] = "OPR_OR",
  3271. }
  3272. function luaY:getbinopr(op)
  3273. local opr = self.getbinopr_table[op]
  3274. if opr then return opr else return "OPR_NOBINOPR" end
  3275. end
  3276.  
  3277. ------------------------------------------------------------------------
  3278. -- the following priority table consists of pairs of left/right values
  3279. -- for binary operators (was a static const struct); grep for ORDER OPR
  3280. -- * the following struct is replaced:
  3281. -- static const struct {
  3282. -- lu_byte left; /* left priority for each binary operator */
  3283. -- lu_byte right; /* right priority */
  3284. -- } priority[] = { /* ORDER OPR */
  3285. ------------------------------------------------------------------------
  3286. luaY.priority = {
  3287. {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, -- `+' `-' `/' `%'
  3288. {10, 9}, {5, 4}, -- power and concat (right associative)
  3289. {3, 3}, {3, 3}, -- equality
  3290. {3, 3}, {3, 3}, {3, 3}, {3, 3}, -- order
  3291. {2, 2}, {1, 1} -- logical (and/or)
  3292. }
  3293.  
  3294. luaY.UNARY_PRIORITY = 8 -- priority for unary operators
  3295.  
  3296. ------------------------------------------------------------------------
  3297. -- Parse subexpressions. Includes handling of unary operators and binary
  3298. -- operators. A subexpr is given the rhs priority level of the operator
  3299. -- immediately left of it, if any (limit is -1 if none,) and if a binop
  3300. -- is found, limit is compared with the lhs priority level of the binop
  3301. -- in order to determine which executes first.
  3302. ------------------------------------------------------------------------
  3303.  
  3304. ------------------------------------------------------------------------
  3305. -- subexpr -> (simpleexp | unop subexpr) { binop subexpr }
  3306. -- where 'binop' is any binary operator with a priority higher than 'limit'
  3307. -- * for priority lookups with self.priority[], 1=left and 2=right
  3308. -- * recursively called
  3309. -- * used in expr()
  3310. ------------------------------------------------------------------------
  3311. function luaY:subexpr(ls, v, limit)
  3312. self:enterlevel(ls)
  3313. local uop = self:getunopr(ls.t.token)
  3314. if uop ~= "OPR_NOUNOPR" then
  3315. luaX:next(ls)
  3316. self:subexpr(ls, v, self.UNARY_PRIORITY)
  3317. luaK:prefix(ls.fs, uop, v)
  3318. else
  3319. self:simpleexp(ls, v)
  3320. end
  3321. -- expand while operators have priorities higher than 'limit'
  3322. local op = self:getbinopr(ls.t.token)
  3323. while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do
  3324. local v2 = {} -- expdesc
  3325. luaX:next(ls)
  3326. luaK:infix(ls.fs, op, v)
  3327. -- read sub-expression with higher priority
  3328. local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2])
  3329. luaK:posfix(ls.fs, op, v, v2)
  3330. op = nextop
  3331. end
  3332. self:leavelevel(ls)
  3333. return op -- return first untreated operator
  3334. end
  3335.  
  3336. ------------------------------------------------------------------------
  3337. -- Expression parsing starts here. Function subexpr is entered with the
  3338. -- left operator (which is non-existent) priority of -1, which is lower
  3339. -- than all actual operators. Expr information is returned in parm v.
  3340. -- * used in multiple locations
  3341. ------------------------------------------------------------------------
  3342. function luaY:expr(ls, v)
  3343. self:subexpr(ls, v, 0)
  3344. end
  3345.  
  3346. -- }====================================================================
  3347.  
  3348. --[[--------------------------------------------------------------------
  3349. -- Rules for Statements
  3350. ----------------------------------------------------------------------]]
  3351.  
  3352. ------------------------------------------------------------------------
  3353. -- checks next token, used as a look-ahead
  3354. -- * returns boolean instead of 0|1
  3355. -- * used in retstat(), chunk()
  3356. ------------------------------------------------------------------------
  3357. function luaY:block_follow(token)
  3358. if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END"
  3359. or token == "TK_UNTIL" or token == "TK_EOS" then
  3360. return true
  3361. else
  3362. return false
  3363. end
  3364. end
  3365.  
  3366. ------------------------------------------------------------------------
  3367. -- parse a code block or unit
  3368. -- * used in multiple functions
  3369. ------------------------------------------------------------------------
  3370. function luaY:block(ls)
  3371. -- block -> chunk
  3372. local fs = ls.fs
  3373. local bl = {} -- BlockCnt
  3374. self:enterblock(fs, bl, false)
  3375. self:chunk(ls)
  3376. assert(bl.breaklist == luaK.NO_JUMP)
  3377. self:leaveblock(fs)
  3378. end
  3379.  
  3380. ------------------------------------------------------------------------
  3381. -- structure to chain all variables in the left-hand side of an
  3382. -- assignment
  3383. -- struct LHS_assign:
  3384. -- prev -- (table: struct LHS_assign)
  3385. -- v -- variable (global, local, upvalue, or indexed) (table: expdesc)
  3386. ------------------------------------------------------------------------
  3387.  
  3388. ------------------------------------------------------------------------
  3389. -- check whether, in an assignment to a local variable, the local variable
  3390. -- is needed in a previous assignment (to a table). If so, save original
  3391. -- local value in a safe place and use this safe copy in the previous
  3392. -- assignment.
  3393. -- * used in assignment()
  3394. ------------------------------------------------------------------------
  3395. function luaY:check_conflict(ls, lh, v)
  3396. local fs = ls.fs
  3397. local extra = fs.freereg -- eventual position to save local variable
  3398. local conflict = false
  3399. while lh do
  3400. if lh.v.k == "VINDEXED" then
  3401. if lh.v.info == v.info then -- conflict?
  3402. conflict = true
  3403. lh.v.info = extra -- previous assignment will use safe copy
  3404. end
  3405. if lh.v.aux == v.info then -- conflict?
  3406. conflict = true
  3407. lh.v.aux = extra -- previous assignment will use safe copy
  3408. end
  3409. end
  3410. lh = lh.prev
  3411. end
  3412. if conflict then
  3413. luaK:codeABC(fs, "OP_MOVE", fs.freereg, v.info, 0) -- make copy
  3414. luaK:reserveregs(fs, 1)
  3415. end
  3416. end
  3417.  
  3418. ------------------------------------------------------------------------
  3419. -- parse a variable assignment sequence
  3420. -- * recursively called
  3421. -- * used in exprstat()
  3422. ------------------------------------------------------------------------
  3423. function luaY:assignment(ls, lh, nvars)
  3424. local e = {} -- expdesc
  3425. -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED
  3426. local c = lh.v.k
  3427. self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL"
  3428. or c == "VINDEXED", "syntax error")
  3429. if self:testnext(ls, ",") then -- assignment -> ',' primaryexp assignment
  3430. local nv = {} -- LHS_assign
  3431. nv.v = {}
  3432. nv.prev = lh
  3433. self:primaryexp(ls, nv.v)
  3434. if nv.v.k == "VLOCAL" then
  3435. self:check_conflict(ls, lh, nv.v)
  3436. end
  3437. self:checklimit(ls.fs, nvars, self.LUAI_MAXCCALLS - ls.L.nCcalls,
  3438. "variables in assignment")
  3439. self:assignment(ls, nv, nvars + 1)
  3440. else -- assignment -> '=' explist1
  3441. self:checknext(ls, "=")
  3442. local nexps = self:explist1(ls, e)
  3443. if nexps ~= nvars then
  3444. self:adjust_assign(ls, nvars, nexps, e)
  3445. if nexps > nvars then
  3446. ls.fs.freereg = ls.fs.freereg - (nexps - nvars) -- remove extra values
  3447. end
  3448. else
  3449. luaK:setoneret(ls.fs, e) -- close last expression
  3450. luaK:storevar(ls.fs, lh.v, e)
  3451. return -- avoid default
  3452. end
  3453. end
  3454. self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1) -- default assignment
  3455. luaK:storevar(ls.fs, lh.v, e)
  3456. end
  3457.  
  3458. ------------------------------------------------------------------------
  3459. -- parse condition in a repeat statement or an if control structure
  3460. -- * used in repeatstat(), test_then_block()
  3461. ------------------------------------------------------------------------
  3462. function luaY:cond(ls)
  3463. -- cond -> exp
  3464. local v = {} -- expdesc
  3465. self:expr(ls, v) -- read condition
  3466. if v.k == "VNIL" then v.k = "VFALSE" end -- 'falses' are all equal here
  3467. luaK:goiftrue(ls.fs, v)
  3468. return v.f
  3469. end
  3470.  
  3471. ------------------------------------------------------------------------
  3472. -- parse a break statement
  3473. -- * used in statements()
  3474. ------------------------------------------------------------------------
  3475. function luaY:breakstat(ls)
  3476. -- stat -> BREAK
  3477. local fs = ls.fs
  3478. local bl = fs.bl
  3479. local upval = false
  3480. while bl and not bl.isbreakable do
  3481. if bl.upval then upval = true end
  3482. bl = bl.previous
  3483. end
  3484. if not bl then
  3485. luaX:syntaxerror(ls, "no loop to break")
  3486. end
  3487. if upval then
  3488. luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
  3489. end
  3490. bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs))
  3491. end
  3492.  
  3493. ------------------------------------------------------------------------
  3494. -- parse a while-do control structure, body processed by block()
  3495. -- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by
  3496. -- the function's implementation can be removed
  3497. -- * used in statements()
  3498. ------------------------------------------------------------------------
  3499. function luaY:whilestat(ls, line)
  3500. -- whilestat -> WHILE cond DO block END
  3501. local fs = ls.fs
  3502. local bl = {} -- BlockCnt
  3503. luaX:next(ls) -- skip WHILE
  3504. local whileinit = luaK:getlabel(fs)
  3505. local condexit = self:cond(ls)
  3506. self:enterblock(fs, bl, true)
  3507. self:checknext(ls, "TK_DO")
  3508. self:block(ls)
  3509. luaK:patchlist(fs, luaK:jump(fs), whileinit)
  3510. self:check_match(ls, "TK_END", "TK_WHILE", line)
  3511. self:leaveblock(fs)
  3512. luaK:patchtohere(fs, condexit) -- false conditions finish the loop
  3513. end
  3514.  
  3515. ------------------------------------------------------------------------
  3516. -- parse a repeat-until control structure, body parsed by chunk()
  3517. -- * used in statements()
  3518. ------------------------------------------------------------------------
  3519. function luaY:repeatstat(ls, line)
  3520. -- repeatstat -> REPEAT block UNTIL cond
  3521. local fs = ls.fs
  3522. local repeat_init = luaK:getlabel(fs)
  3523. local bl1, bl2 = {}, {} -- BlockCnt
  3524. self:enterblock(fs, bl1, true) -- loop block
  3525. self:enterblock(fs, bl2, false) -- scope block
  3526. luaX:next(ls) -- skip REPEAT
  3527. self:chunk(ls)
  3528. self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line)
  3529. local condexit = self:cond(ls) -- read condition (inside scope block)
  3530. if not bl2.upval then -- no upvalues?
  3531. self:leaveblock(fs) -- finish scope
  3532. luaK:patchlist(ls.fs, condexit, repeat_init) -- close the loop
  3533. else -- complete semantics when there are upvalues
  3534. self:breakstat(ls) -- if condition then break
  3535. luaK:patchtohere(ls.fs, condexit) -- else...
  3536. self:leaveblock(fs) -- finish scope...
  3537. luaK:patchlist(ls.fs, luaK:jump(fs), repeat_init) -- and repeat
  3538. end
  3539. self:leaveblock(fs) -- finish loop
  3540. end
  3541.  
  3542. ------------------------------------------------------------------------
  3543. -- parse the single expressions needed in numerical for loops
  3544. -- * used in fornum()
  3545. ------------------------------------------------------------------------
  3546. function luaY:exp1(ls)
  3547. local e = {} -- expdesc
  3548. self:expr(ls, e)
  3549. local k = e.k
  3550. luaK:exp2nextreg(ls.fs, e)
  3551. return k
  3552. end
  3553.  
  3554. ------------------------------------------------------------------------
  3555. -- parse a for loop body for both versions of the for loop
  3556. -- * used in fornum(), forlist()
  3557. ------------------------------------------------------------------------
  3558. function luaY:forbody(ls, base, line, nvars, isnum)
  3559. -- forbody -> DO block
  3560. local bl = {} -- BlockCnt
  3561. local fs = ls.fs
  3562. self:adjustlocalvars(ls, 3) -- control variables
  3563. self:checknext(ls, "TK_DO")
  3564. local prep = isnum and luaK:codeAsBx(fs, "OP_FORPREP", base, luaK.NO_JUMP)
  3565. or luaK:jump(fs)
  3566. self:enterblock(fs, bl, false) -- scope for declared variables
  3567. self:adjustlocalvars(ls, nvars)
  3568. luaK:reserveregs(fs, nvars)
  3569. self:block(ls)
  3570. self:leaveblock(fs) -- end of scope for declared variables
  3571. luaK:patchtohere(fs, prep)
  3572. local endfor = isnum and luaK:codeAsBx(fs, "OP_FORLOOP", base, luaK.NO_JUMP)
  3573. or luaK:codeABC(fs, "OP_TFORLOOP", base, 0, nvars)
  3574. luaK:fixline(fs, line) -- pretend that `OP_FOR' starts the loop
  3575. luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep + 1)
  3576. end
  3577.  
  3578. ------------------------------------------------------------------------
  3579. -- parse a numerical for loop, calls forbody()
  3580. -- * used in forstat()
  3581. ------------------------------------------------------------------------
  3582. function luaY:fornum(ls, varname, line)
  3583. -- fornum -> NAME = exp1,exp1[,exp1] forbody
  3584. local fs = ls.fs
  3585. local base = fs.freereg
  3586. self:new_localvarliteral(ls, "(for index)", 0)
  3587. self:new_localvarliteral(ls, "(for limit)", 1)
  3588. self:new_localvarliteral(ls, "(for step)", 2)
  3589. self:new_localvar(ls, varname, 3)
  3590. self:checknext(ls, '=')
  3591. self:exp1(ls) -- initial value
  3592. self:checknext(ls, ",")
  3593. self:exp1(ls) -- limit
  3594. if self:testnext(ls, ",") then
  3595. self:exp1(ls) -- optional step
  3596. else -- default step = 1
  3597. luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1))
  3598. luaK:reserveregs(fs, 1)
  3599. end
  3600. self:forbody(ls, base, line, 1, true)
  3601. end
  3602.  
  3603. ------------------------------------------------------------------------
  3604. -- parse a generic for loop, calls forbody()
  3605. -- * used in forstat()
  3606. ------------------------------------------------------------------------
  3607. function luaY:forlist(ls, indexname)
  3608. -- forlist -> NAME {,NAME} IN explist1 forbody
  3609. local fs = ls.fs
  3610. local e = {} -- expdesc
  3611. local nvars = 0
  3612. local base = fs.freereg
  3613. -- create control variables
  3614. self:new_localvarliteral(ls, "(for generator)", nvars)
  3615. nvars = nvars + 1
  3616. self:new_localvarliteral(ls, "(for state)", nvars)
  3617. nvars = nvars + 1
  3618. self:new_localvarliteral(ls, "(for control)", nvars)
  3619. nvars = nvars + 1
  3620. -- create declared variables
  3621. self:new_localvar(ls, indexname, nvars)
  3622. nvars = nvars + 1
  3623. while self:testnext(ls, ",") do
  3624. self:new_localvar(ls, self:str_checkname(ls), nvars)
  3625. nvars = nvars + 1
  3626. end
  3627. self:checknext(ls, "TK_IN")
  3628. local line = ls.linenumber
  3629. self:adjust_assign(ls, 3, self:explist1(ls, e), e)
  3630. luaK:checkstack(fs, 3) -- extra space to call generator
  3631. self:forbody(ls, base, line, nvars - 3, false)
  3632. end
  3633.  
  3634. ------------------------------------------------------------------------
  3635. -- initial parsing for a for loop, calls fornum() or forlist()
  3636. -- * used in statements()
  3637. ------------------------------------------------------------------------
  3638. function luaY:forstat(ls, line)
  3639. -- forstat -> FOR (fornum | forlist) END
  3640. local fs = ls.fs
  3641. local bl = {} -- BlockCnt
  3642. self:enterblock(fs, bl, true) -- scope for loop and control variables
  3643. luaX:next(ls) -- skip `for'
  3644. local varname = self:str_checkname(ls) -- first variable name
  3645. local c = ls.t.token
  3646. if c == "=" then
  3647. self:fornum(ls, varname, line)
  3648. elseif c == "," or c == "TK_IN" then
  3649. self:forlist(ls, varname)
  3650. else
  3651. luaX:syntaxerror(ls, self:LUA_QL("=").." or "..self:LUA_QL("in").." expected")
  3652. end
  3653. self:check_match(ls, "TK_END", "TK_FOR", line)
  3654. self:leaveblock(fs) -- loop scope (`break' jumps to this point)
  3655. end
  3656.  
  3657. ------------------------------------------------------------------------
  3658. -- parse part of an if control structure, including the condition
  3659. -- * used in ifstat()
  3660. ------------------------------------------------------------------------
  3661. function luaY:test_then_block(ls)
  3662. -- test_then_block -> [IF | ELSEIF] cond THEN block
  3663. luaX:next(ls) -- skip IF or ELSEIF
  3664. local condexit = self:cond(ls)
  3665. self:checknext(ls, "TK_THEN")
  3666. self:block(ls) -- `then' part
  3667. return condexit
  3668. end
  3669.  
  3670. ------------------------------------------------------------------------
  3671. -- parse an if control structure
  3672. -- * used in statements()
  3673. ------------------------------------------------------------------------
  3674. function luaY:ifstat(ls, line)
  3675. -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END
  3676. local fs = ls.fs
  3677. local escapelist = luaK.NO_JUMP
  3678. local flist = self:test_then_block(ls) -- IF cond THEN block
  3679. while ls.t.token == "TK_ELSEIF" do
  3680. escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
  3681. luaK:patchtohere(fs, flist)
  3682. flist = self:test_then_block(ls) -- ELSEIF cond THEN block
  3683. end
  3684. if ls.t.token == "TK_ELSE" then
  3685. escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
  3686. luaK:patchtohere(fs, flist)
  3687. luaX:next(ls) -- skip ELSE (after patch, for correct line info)
  3688. self:block(ls) -- 'else' part
  3689. else
  3690. escapelist = luaK:concat(fs, escapelist, flist)
  3691. end
  3692. luaK:patchtohere(fs, escapelist)
  3693. self:check_match(ls, "TK_END", "TK_IF", line)
  3694. end
  3695.  
  3696. ------------------------------------------------------------------------
  3697. -- parse a local function statement
  3698. -- * used in statements()
  3699. ------------------------------------------------------------------------
  3700. function luaY:localfunc(ls)
  3701. local v, b = {}, {} -- expdesc
  3702. local fs = ls.fs
  3703. self:new_localvar(ls, self:str_checkname(ls), 0)
  3704. self:init_exp(v, "VLOCAL", fs.freereg)
  3705. luaK:reserveregs(fs, 1)
  3706. self:adjustlocalvars(ls, 1)
  3707. self:body(ls, b, false, ls.linenumber)
  3708. luaK:storevar(fs, v, b)
  3709. -- debug information will only see the variable after this point!
  3710. self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc
  3711. end
  3712.  
  3713. ------------------------------------------------------------------------
  3714. -- parse a local variable declaration statement
  3715. -- * used in statements()
  3716. ------------------------------------------------------------------------
  3717. function luaY:localstat(ls)
  3718. -- stat -> LOCAL NAME {',' NAME} ['=' explist1]
  3719. local nvars = 0
  3720. local nexps
  3721. local e = {} -- expdesc
  3722. repeat
  3723. self:new_localvar(ls, self:str_checkname(ls), nvars)
  3724. nvars = nvars + 1
  3725. until not self:testnext(ls, ",")
  3726. if self:testnext(ls, "=") then
  3727. nexps = self:explist1(ls, e)
  3728. else
  3729. e.k = "VVOID"
  3730. nexps = 0
  3731. end
  3732. self:adjust_assign(ls, nvars, nexps, e)
  3733. self:adjustlocalvars(ls, nvars)
  3734. end
  3735.  
  3736. ------------------------------------------------------------------------
  3737. -- parse a function name specification
  3738. -- * used in funcstat()
  3739. ------------------------------------------------------------------------
  3740. function luaY:funcname(ls, v)
  3741. -- funcname -> NAME {field} [':' NAME]
  3742. local needself = false
  3743. self:singlevar(ls, v)
  3744. while ls.t.token == "." do
  3745. self:field(ls, v)
  3746. end
  3747. if ls.t.token == ":" then
  3748. needself = true
  3749. self:field(ls, v)
  3750. end
  3751. return needself
  3752. end
  3753.  
  3754. ------------------------------------------------------------------------
  3755. -- parse a function statement
  3756. -- * used in statements()
  3757. ------------------------------------------------------------------------
  3758. function luaY:funcstat(ls, line)
  3759. -- funcstat -> FUNCTION funcname body
  3760. local v, b = {}, {} -- expdesc
  3761. luaX:next(ls) -- skip FUNCTION
  3762. local needself = self:funcname(ls, v)
  3763. self:body(ls, b, needself, line)
  3764. luaK:storevar(ls.fs, v, b)
  3765. luaK:fixline(ls.fs, line) -- definition 'happens' in the first line
  3766. end
  3767.  
  3768. ------------------------------------------------------------------------
  3769. -- parse a function call with no returns or an assignment statement
  3770. -- * used in statements()
  3771. ------------------------------------------------------------------------
  3772. function luaY:exprstat(ls)
  3773. -- stat -> func | assignment
  3774. local fs = ls.fs
  3775. local v = {} -- LHS_assign
  3776. v.v = {}
  3777. self:primaryexp(ls, v.v)
  3778. if v.v.k == "VCALL" then -- stat -> func
  3779. luaP:SETARG_C(luaK:getcode(fs, v.v), 1) -- call statement uses no results
  3780. else -- stat -> assignment
  3781. v.prev = nil
  3782. self:assignment(ls, v, 1)
  3783. end
  3784. end
  3785.  
  3786. ------------------------------------------------------------------------
  3787. -- parse a return statement
  3788. -- * used in statements()
  3789. ------------------------------------------------------------------------
  3790. function luaY:retstat(ls)
  3791. -- stat -> RETURN explist
  3792. local fs = ls.fs
  3793. local e = {} -- expdesc
  3794. local first, nret -- registers with returned values
  3795. luaX:next(ls) -- skip RETURN
  3796. if self:block_follow(ls.t.token) or ls.t.token == ";" then
  3797. first, nret = 0, 0 -- return no values
  3798. else
  3799. nret = self:explist1(ls, e) -- optional return values
  3800. if self:hasmultret(e.k) then
  3801. luaK:setmultret(fs, e)
  3802. if e.k == "VCALL" and nret == 1 then -- tail call?
  3803. luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL")
  3804. assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar)
  3805. end
  3806. first = fs.nactvar
  3807. nret = self.LUA_MULTRET -- return all values
  3808. else
  3809. if nret == 1 then -- only one single value?
  3810. first = luaK:exp2anyreg(fs, e)
  3811. else
  3812. luaK:exp2nextreg(fs, e) -- values must go to the 'stack'
  3813. first = fs.nactvar -- return all 'active' values
  3814. assert(nret == fs.freereg - first)
  3815. end
  3816. end--if
  3817. end--if
  3818. luaK:ret(fs, first, nret)
  3819. end
  3820.  
  3821. ------------------------------------------------------------------------
  3822. -- initial parsing for statements, calls a lot of functions
  3823. -- * returns boolean instead of 0|1
  3824. -- * used in chunk()
  3825. ------------------------------------------------------------------------
  3826. function luaY:statement(ls)
  3827. local line = ls.linenumber -- may be needed for error messages
  3828. local c = ls.t.token
  3829. if c == "TK_IF" then -- stat -> ifstat
  3830. self:ifstat(ls, line)
  3831. return false
  3832. elseif c == "TK_WHILE" then -- stat -> whilestat
  3833. self:whilestat(ls, line)
  3834. return false
  3835. elseif c == "TK_DO" then -- stat -> DO block END
  3836. luaX:next(ls) -- skip DO
  3837. self:block(ls)
  3838. self:check_match(ls, "TK_END", "TK_DO", line)
  3839. return false
  3840. elseif c == "TK_FOR" then -- stat -> forstat
  3841. self:forstat(ls, line)
  3842. return false
  3843. elseif c == "TK_REPEAT" then -- stat -> repeatstat
  3844. self:repeatstat(ls, line)
  3845. return false
  3846. elseif c == "TK_FUNCTION" then -- stat -> funcstat
  3847. self:funcstat(ls, line)
  3848. return false
  3849. elseif c == "TK_LOCAL" then -- stat -> localstat
  3850. luaX:next(ls) -- skip LOCAL
  3851. if self:testnext(ls, "TK_FUNCTION") then -- local function?
  3852. self:localfunc(ls)
  3853. else
  3854. self:localstat(ls)
  3855. end
  3856. return false
  3857. elseif c == "TK_RETURN" then -- stat -> retstat
  3858. self:retstat(ls)
  3859. return true -- must be last statement
  3860. elseif c == "TK_BREAK" then -- stat -> breakstat
  3861. luaX:next(ls) -- skip BREAK
  3862. self:breakstat(ls)
  3863. return true -- must be last statement
  3864. else
  3865. self:exprstat(ls)
  3866. return false -- to avoid warnings
  3867. end--if c
  3868. end
  3869.  
  3870. ------------------------------------------------------------------------
  3871. -- parse a chunk, which consists of a bunch of statements
  3872. -- * used in parser(), body(), block(), repeatstat()
  3873. ------------------------------------------------------------------------
  3874. function luaY:chunk(ls)
  3875. -- chunk -> { stat [';'] }
  3876. local islast = false
  3877. self:enterlevel(ls)
  3878. while not islast and not self:block_follow(ls.t.token) do
  3879. islast = self:statement(ls)
  3880. self:testnext(ls, ";")
  3881. assert(ls.fs.f.maxstacksize >= ls.fs.freereg and
  3882. ls.fs.freereg >= ls.fs.nactvar)
  3883. ls.fs.freereg = ls.fs.nactvar -- free registers
  3884. end
  3885. self:leavelevel(ls)
  3886. end
  3887.  
  3888. -- }======================================================================
  3889. return luaY
  3890. end
  3891. luaY=luaY()
  3892. local luaU = function ()
  3893. local luaU = {}
  3894. local luaP = luaP
  3895.  
  3896. -- mark for precompiled code ('<esc>Lua') (from lua.h)
  3897. luaU.LUA_SIGNATURE = "\27Lua"
  3898.  
  3899. -- constants used by dumper (from lua.h)
  3900. luaU.LUA_TNUMBER = 3
  3901. luaU.LUA_TSTRING = 4
  3902. luaU.LUA_TNIL = 0
  3903. luaU.LUA_TBOOLEAN = 1
  3904. luaU.LUA_TNONE = -1
  3905.  
  3906. -- constants for header of binary files (from lundump.h)
  3907. luaU.LUAC_VERSION = 0x51 -- this is Lua 5.1
  3908. luaU.LUAC_FORMAT = 0 -- this is the official format
  3909. luaU.LUAC_HEADERSIZE = 12 -- size of header of binary files
  3910.  
  3911. --[[--------------------------------------------------------------------
  3912. -- Additional functions to handle chunk writing
  3913. -- * to use make_setS and make_setF, see test_ldump.lua elsewhere
  3914. ----------------------------------------------------------------------]]
  3915.  
  3916. ------------------------------------------------------------------------
  3917. -- create a chunk writer that writes to a string
  3918. -- * returns the writer function and a table containing the string
  3919. -- * to get the final result, look in buff.data
  3920. ------------------------------------------------------------------------
  3921. function luaU:make_setS()
  3922. local buff = {}
  3923. buff.data = ""
  3924. local writer =
  3925. function(s, buff) -- chunk writer
  3926. if not s then return 0 end
  3927. buff.data = buff.data..s
  3928. return 0
  3929. end
  3930. return writer, buff
  3931. end
  3932.  
  3933. ------------------------------------------------------------------------
  3934. -- create a chunk writer that writes to a file
  3935. -- * returns the writer function and a table containing the file handle
  3936. -- * if a nil is passed, then writer should close the open file
  3937. ------------------------------------------------------------------------
  3938.  
  3939. --[[
  3940. function luaU:make_setF(filename)
  3941. local buff = {}
  3942. buff.h = io.open(filename, "wb")
  3943. if not buff.h then return nil end
  3944. local writer =
  3945. function(s, buff) -- chunk writer
  3946. if not buff.h then return 0 end
  3947. if not s then
  3948. if buff.h:close() then return 0 end
  3949. else
  3950. if buff.h:write(s) then return 0 end
  3951. end
  3952. return 1
  3953. end
  3954. return writer, buff
  3955. end--]]
  3956.  
  3957. ------------------------------------------------------------------------
  3958. -- works like the lobject.h version except that TObject used in these
  3959. -- scripts only has a 'value' field, no 'tt' field (native types used)
  3960. ------------------------------------------------------------------------
  3961. function luaU:ttype(o)
  3962. local tt = type(o.value)
  3963. if tt == "number" then return self.LUA_TNUMBER
  3964. elseif tt == "string" then return self.LUA_TSTRING
  3965. elseif tt == "nil" then return self.LUA_TNIL
  3966. elseif tt == "boolean" then return self.LUA_TBOOLEAN
  3967. else
  3968. return self.LUA_TNONE -- the rest should not appear
  3969. end
  3970. end
  3971.  
  3972. -----------------------------------------------------------------------
  3973. -- converts a IEEE754 double number to an 8-byte little-endian string
  3974. -- * luaU:from_double() and luaU:from_int() are adapted from ChunkBake
  3975. -- * supports +/- Infinity, but not denormals or NaNs
  3976. -----------------------------------------------------------------------
  3977. function luaU:from_double(x)
  3978. local function grab_byte(v)
  3979. local c = v % 256
  3980. return (v - c) / 256, string.char(c)
  3981. end
  3982. local sign = 0
  3983. if x < 0 then sign = 1; x = -x end
  3984. local mantissa, exponent = math.frexp(x)
  3985. if x == 0 then -- zero
  3986. mantissa, exponent = 0, 0
  3987. elseif x == 1/0 then
  3988. mantissa, exponent = 0, 2047
  3989. else
  3990. mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, 53)
  3991. exponent = exponent + 1022
  3992. end
  3993. local v, byte = "" -- convert to bytes
  3994. x = math.floor(mantissa)
  3995. for i = 1,6 do
  3996. x, byte = grab_byte(x); v = v..byte -- 47:0
  3997. end
  3998. x, byte = grab_byte(exponent * 16 + x); v = v..byte -- 55:48
  3999. x, byte = grab_byte(sign * 128 + x); v = v..byte -- 63:56
  4000. return v
  4001. end
  4002.  
  4003. -----------------------------------------------------------------------
  4004. -- converts a number to a little-endian 32-bit integer string
  4005. -- * input value assumed to not overflow, can be signed/unsigned
  4006. -----------------------------------------------------------------------
  4007. function luaU:from_int(x)
  4008. local v = ""
  4009. x = math.floor(x)
  4010. if x < 0 then x = 4294967296 + x end -- ULONG_MAX+1
  4011. for i = 1, 4 do
  4012. local c = x % 256
  4013. v = v..string.char(c); x = math.floor(x / 256)
  4014. end
  4015. return v
  4016. end
  4017.  
  4018. --[[--------------------------------------------------------------------
  4019. -- Functions to make a binary chunk
  4020. -- * many functions have the size parameter removed, since output is
  4021. -- in the form of a string and some sizes are implicit or hard-coded
  4022. ----------------------------------------------------------------------]]
  4023.  
  4024. --[[--------------------------------------------------------------------
  4025. -- struct DumpState:
  4026. -- L -- lua_State (not used in this script)
  4027. -- writer -- lua_Writer (chunk writer function)
  4028. -- data -- void* (chunk writer context or data already written)
  4029. -- strip -- if true, don't write any debug information
  4030. -- status -- if non-zero, an error has occured
  4031. ----------------------------------------------------------------------]]
  4032.  
  4033. ------------------------------------------------------------------------
  4034. -- dumps a block of bytes
  4035. -- * lua_unlock(D.L), lua_lock(D.L) unused
  4036. ------------------------------------------------------------------------
  4037. function luaU:DumpBlock(b, D)
  4038. if D.status == 0 then
  4039. -- lua_unlock(D->L);
  4040. D.status = D.write(b, D.data)
  4041. -- lua_lock(D->L);
  4042. end
  4043. end
  4044.  
  4045. ------------------------------------------------------------------------
  4046. -- dumps a char
  4047. ------------------------------------------------------------------------
  4048. function luaU:DumpChar(y, D)
  4049. self:DumpBlock(string.char(y), D)
  4050. end
  4051.  
  4052. ------------------------------------------------------------------------
  4053. -- dumps a 32-bit signed or unsigned integer (for int) (hard-coded)
  4054. ------------------------------------------------------------------------
  4055. function luaU:DumpInt(x, D)
  4056. self:DumpBlock(self:from_int(x), D)
  4057. end
  4058.  
  4059. ------------------------------------------------------------------------
  4060. -- dumps a lua_Number (hard-coded as a double)
  4061. ------------------------------------------------------------------------
  4062. function luaU:DumpNumber(x, D)
  4063. self:DumpBlock(self:from_double(x), D)
  4064. end
  4065.  
  4066. ------------------------------------------------------------------------
  4067. -- dumps a Lua string (size type is hard-coded)
  4068. ------------------------------------------------------------------------
  4069. function luaU:DumpString(s, D)
  4070. if s == nil then
  4071. self:DumpInt(0, D)
  4072. else
  4073. s = s.."\0" -- include trailing '\0'
  4074. self:DumpInt(#s, D)
  4075. self:DumpBlock(s, D)
  4076. end
  4077. end
  4078.  
  4079. ------------------------------------------------------------------------
  4080. -- dumps instruction block from function prototype
  4081. ------------------------------------------------------------------------
  4082. function luaU:DumpCode(f, D)
  4083. local n = f.sizecode
  4084. --was DumpVector
  4085. self:DumpInt(n, D)
  4086. for i = 0, n - 1 do
  4087. self:DumpBlock(luaP:Instruction(f.code[i]), D)
  4088. end
  4089. end
  4090.  
  4091. ------------------------------------------------------------------------
  4092. -- dump constant pool from function prototype
  4093. -- * bvalue(o), nvalue(o) and rawtsvalue(o) macros removed
  4094. ------------------------------------------------------------------------
  4095. function luaU:DumpConstants(f, D)
  4096. local n = f.sizek
  4097. self:DumpInt(n, D)
  4098. for i = 0, n - 1 do
  4099. local o = f.k[i] -- TValue
  4100. local tt = self:ttype(o)
  4101. self:DumpChar(tt, D)
  4102. if tt == self.LUA_TNIL then
  4103. elseif tt == self.LUA_TBOOLEAN then
  4104. self:DumpChar(o.value and 1 or 0, D)
  4105. elseif tt == self.LUA_TNUMBER then
  4106. self:DumpNumber(o.value, D)
  4107. elseif tt == self.LUA_TSTRING then
  4108. self:DumpString(o.value, D)
  4109. else
  4110. --lua_assert(0) -- cannot happen
  4111. end
  4112. end
  4113. n = f.sizep
  4114. self:DumpInt(n, D)
  4115. for i = 0, n - 1 do
  4116. self:DumpFunction(f.p[i], f.source, D)
  4117. end
  4118. end
  4119.  
  4120. ------------------------------------------------------------------------
  4121. -- dump debug information
  4122. ------------------------------------------------------------------------
  4123. function luaU:DumpDebug(f, D)
  4124. local n
  4125. n = D.strip and 0 or f.sizelineinfo -- dump line information
  4126. --was DumpVector
  4127. self:DumpInt(n, D)
  4128. for i = 0, n - 1 do
  4129. self:DumpInt(f.lineinfo[i], D)
  4130. end
  4131. n = D.strip and 0 or f.sizelocvars -- dump local information
  4132. self:DumpInt(n, D)
  4133. for i = 0, n - 1 do
  4134. self:DumpString(f.locvars[i].varname, D)
  4135. self:DumpInt(f.locvars[i].startpc, D)
  4136. self:DumpInt(f.locvars[i].endpc, D)
  4137. end
  4138. n = D.strip and 0 or f.sizeupvalues -- dump upvalue information
  4139. self:DumpInt(n, D)
  4140. for i = 0, n - 1 do
  4141. self:DumpString(f.upvalues[i], D)
  4142. end
  4143. end
  4144.  
  4145. ------------------------------------------------------------------------
  4146. -- dump child function prototypes from function prototype
  4147. ------------------------------------------------------------------------
  4148. function luaU:DumpFunction(f, p, D)
  4149. local source = f.source
  4150. if source == p or D.strip then source = nil end
  4151. self:DumpString(source, D)
  4152. self:DumpInt(f.lineDefined, D)
  4153. self:DumpInt(f.lastlinedefined, D)
  4154. self:DumpChar(f.nups, D)
  4155. self:DumpChar(f.numparams, D)
  4156. self:DumpChar(f.is_vararg, D)
  4157. self:DumpChar(f.maxstacksize, D)
  4158. self:DumpCode(f, D)
  4159. self:DumpConstants(f, D)
  4160. self:DumpDebug(f, D)
  4161. end
  4162.  
  4163. ------------------------------------------------------------------------
  4164. -- dump Lua header section (some sizes hard-coded)
  4165. ------------------------------------------------------------------------
  4166. function luaU:DumpHeader(D)
  4167. local h = self:header()
  4168. assert(#h == self.LUAC_HEADERSIZE) -- fixed buffer now an assert
  4169. self:DumpBlock(h, D)
  4170. end
  4171.  
  4172. ------------------------------------------------------------------------
  4173. -- make header (from lundump.c)
  4174. -- returns the header string
  4175. ------------------------------------------------------------------------
  4176. function luaU:header()
  4177. local x = 1
  4178. return self.LUA_SIGNATURE..
  4179. string.char(
  4180. self.LUAC_VERSION,
  4181. self.LUAC_FORMAT,
  4182. x, -- endianness (1=little)
  4183. 4, -- sizeof(int)
  4184. 4, -- sizeof(size_t)
  4185. 4, -- sizeof(Instruction)
  4186. 8, -- sizeof(lua_Number)
  4187. 0) -- is lua_Number integral?
  4188. end
  4189.  
  4190. ------------------------------------------------------------------------
  4191. -- dump Lua function as precompiled chunk
  4192. -- (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
  4193. -- * w, data are created from make_setS, make_setF
  4194. ------------------------------------------------------------------------
  4195. function luaU:dump(L, f, w, data, strip)
  4196. local D = {} -- DumpState
  4197. D.L = L
  4198. D.write = w
  4199. D.data = data
  4200. D.strip = strip
  4201. D.status = 0
  4202. self:DumpHeader(D)
  4203. self:DumpFunction(f, nil, D)
  4204. -- added: for a chunk writer writing to a file, this final call with
  4205. -- nil data is to indicate to the writer to close the file
  4206. D.write(nil, D.data)
  4207. return D.status
  4208. end
  4209.  
  4210. return luaU
  4211. end
  4212. luaU=luaU()
  4213. local lbi = function ()
  4214. local advanced_debug
  4215.  
  4216. local lua_opcode_types = {
  4217. "ABC", "ABx", "ABC", "ABC",
  4218. "ABC", "ABx", "ABC", "ABx",
  4219. "ABC", "ABC", "ABC", "ABC",
  4220. "ABC", "ABC", "ABC", "ABC",
  4221. "ABC", "ABC", "ABC", "ABC",
  4222. "ABC", "ABC", "AsBx", "ABC",
  4223. "ABC", "ABC", "ABC", "ABC",
  4224. "ABC", "ABC", "ABC", "AsBx",
  4225. "AsBx", "ABC", "ABC", "ABC",
  4226. "ABx", "ABC",
  4227. }
  4228.  
  4229. local lua_opcode_names = {
  4230. "MOVE", "LOADK", "LOADBOOL", "LOADNIL",
  4231. "GETUPVAL", "GETGLOBAL", "GETTABLE", "SETGLOBAL",
  4232. "SETUPVAL", "SETTABLE", "NEWTABLE", "SELF",
  4233. "ADD", "SUB", "MUL", "DIV",
  4234. "MOD", "POW", "UNM", "NOT",
  4235. "LEN", "CONCAT", "JMP", "EQ",
  4236. "LT", "LE", "TEST", "TESTSET",
  4237. "CALL", "TAILCALL", "RETURN", "FORLOOP",
  4238. "FORPREP", "TFORLOOP", "SETLIST", "CLOSE",
  4239. "CLOSURE", "VARARG"
  4240. };
  4241.  
  4242. local function get_bits(input, n, n2)
  4243. if n2 then
  4244. local total = 0
  4245. local digitn = 0
  4246. for i = n, n2 do
  4247. total = total + 2^digitn*get_bits(input, i)
  4248. digitn = digitn + 1
  4249. end
  4250. return total
  4251. else
  4252. local pn = 2^(n-1)
  4253. return (input % (pn + pn) >= pn) and 1 or 0
  4254. end
  4255. end
  4256.  
  4257. local function decode_bytecode(bytecode)
  4258. local index = 1
  4259. local big_endian = false
  4260. local int_size;
  4261. local size_t;
  4262.  
  4263. -- Actual binary decoding functions. Dependant on the bytecode.
  4264. local get_int, get_size_t;
  4265.  
  4266. -- Binary decoding helper functions
  4267. local get_int8, get_int32, get_int64, get_float64, get_string;
  4268. do
  4269. function get_int8()
  4270. local a = bytecode:byte(index, index);
  4271. index = index + 1
  4272. return a
  4273. end
  4274. function get_int32()
  4275. local a, b, c, d = bytecode:byte(index, index + 3);
  4276. index = index + 4;
  4277. return d*16777216 + c*65536 + b*256 + a
  4278. end
  4279. function get_int64()
  4280. local a = get_int32();
  4281. local b = get_int32();
  4282. return b*4294967296 + a;
  4283. end
  4284. function get_float64()
  4285. local a = get_int32()
  4286. local b = get_int32()
  4287. return (-2*get_bits(b, 32)+1)*(2^(get_bits(b, 21, 31)-1023))*
  4288. ((get_bits(b, 1, 20)*(2^32) + a)/(2^52)+1)
  4289. end
  4290. function get_string(len)
  4291. local str;
  4292. if len then
  4293. str = bytecode:sub(index, index + len - 1);
  4294. index = index + len;
  4295. else
  4296. len = get_size_t();
  4297. if len == 0 then return; end
  4298. str = bytecode:sub(index, index + len - 1);
  4299. index = index + len;
  4300. end
  4301. return str;
  4302. end
  4303. end
  4304.  
  4305. local function decode_chunk()
  4306. local chunk;
  4307. local instructions = {};
  4308. local constants = {};
  4309. local prototypes = {};
  4310. local debug = {
  4311. lines = {};
  4312. };
  4313.  
  4314. chunk = {
  4315. instructions = instructions;
  4316. constants = constants;
  4317. prototypes = prototypes;
  4318. debug = debug;
  4319. };
  4320.  
  4321. local num;
  4322.  
  4323. chunk.name = get_string();-- Function name
  4324. chunk.first_line = get_int(); -- First line
  4325. chunk.last_line = get_int(); -- Last line
  4326.  
  4327. if chunk.name then chunk.name = chunk.name:sub(1, -2); end
  4328.  
  4329. chunk.upvalues = get_int8();
  4330. chunk.arguments = get_int8();
  4331. chunk.varg = get_int8();
  4332. chunk.stack = get_int8();
  4333.  
  4334. -- TODO: realign lists to 1
  4335. -- Decode instructions
  4336. do
  4337. num = get_int();
  4338. for i = 1, num do
  4339. local instruction = {
  4340. -- opcode = opcode number;
  4341. -- type = [ABC, ABx, AsBx]
  4342. -- A, B, C, Bx, or sBx depending on type
  4343. };
  4344.  
  4345. local data = get_int32();
  4346. local opcode = get_bits(data, 1, 6);
  4347. local type = lua_opcode_types[opcode + 1];
  4348.  
  4349. instruction.opcode = opcode;
  4350. instruction.type = type;
  4351.  
  4352. instruction.A = get_bits(data, 7, 14);
  4353. if type == "ABC" then
  4354. instruction.B = get_bits(data, 24, 32);
  4355. instruction.C = get_bits(data, 15, 23);
  4356. elseif type == "ABx" then
  4357. instruction.Bx = get_bits(data, 15, 32);
  4358. elseif type == "AsBx" then
  4359. instruction.sBx = get_bits(data, 15, 32) - 131071;
  4360. end
  4361.  
  4362. instructions[i] = instruction;
  4363. end
  4364. end
  4365.  
  4366. -- Decode constants
  4367. do
  4368. num = get_int();
  4369. for i = 1, num do
  4370. local constant = {
  4371. -- type = constant type;
  4372. -- data = constant data;
  4373. };
  4374. local type = get_int8();
  4375. constant.type = type;
  4376.  
  4377. if type == 1 then
  4378. constant.data = (get_int8() ~= 0);
  4379. elseif type == 3 then
  4380. constant.data = get_float64();
  4381. elseif type == 4 then
  4382. constant.data = get_string():sub(1, -2);
  4383. end
  4384.  
  4385. constants[i-1] = constant;
  4386. end
  4387. end
  4388.  
  4389. -- Decode Prototypes
  4390. do
  4391. num = get_int();
  4392. for i = 1, num do
  4393. prototypes[i-1] = decode_chunk();
  4394. end
  4395. end
  4396.  
  4397. -- Decode debug info
  4398. -- Not all of which is used yet.
  4399. do
  4400. -- line numbers
  4401. local data = debug.lines
  4402. num = get_int();
  4403. for i = 1, num do
  4404. data[i] = get_int32();
  4405. end
  4406.  
  4407. -- locals
  4408. num = get_int();
  4409. for i = 1, num do
  4410. get_string():sub(1, -2); -- local name
  4411. get_int32(); -- local start PC
  4412. get_int32(); -- local end PC
  4413. end
  4414.  
  4415. -- upvalues
  4416. num = get_int();
  4417. for i = 1, num do
  4418. get_string(); -- upvalue name
  4419. end
  4420. end
  4421.  
  4422. return chunk;
  4423. end
  4424.  
  4425. -- Verify bytecode header
  4426. do
  4427. assert(get_string(4) == "\27Lua", "Lua bytecode expected.");
  4428. assert(get_int8() == 0x51, "Only Lua 5.1 is supported.");
  4429. get_int8(); -- Oficial bytecode
  4430. big_endian = (get_int8() == 0);
  4431. int_size = get_int8();
  4432. size_t = get_int8();
  4433.  
  4434. if int_size == 4 then
  4435. get_int = get_int32;
  4436. elseif int_size == 8 then
  4437. get_int = get_int64;
  4438. else
  4439. -- TODO: refactor errors into table
  4440. error("Unsupported bytecode target platform");
  4441. end
  4442.  
  4443. if size_t == 4 then
  4444. get_size_t = get_int32;
  4445. elseif size_t == 8 then
  4446. get_size_t = get_int64;
  4447. else
  4448. error("Unsupported bytecode target platform");
  4449. end
  4450.  
  4451. assert(get_string(3) == "\4\8\0",
  4452. "Unsupported bytecode target platform");
  4453. end
  4454.  
  4455. return decode_chunk();
  4456. end
  4457.  
  4458. local function handle_return(...)
  4459. local c = select("#", ...)
  4460. local t = {...}
  4461. return c, t
  4462. end
  4463.  
  4464. local function create_wrapper(cache, upvalues)
  4465. local instructions = cache.instructions;
  4466. local constants = cache.constants;
  4467. local prototypes = cache.prototypes;
  4468.  
  4469. local stack, top
  4470. local environment
  4471. local IP = 1; -- instruction pointer
  4472. local vararg, vararg_size
  4473.  
  4474. local opcode_funcs = {
  4475. [0] = function(instruction) -- MOVE
  4476. stack[instruction.A] = stack[instruction.B];
  4477. end,
  4478. [1] = function(instruction) -- LOADK
  4479. stack[instruction.A] = constants[instruction.Bx].data;
  4480. end,
  4481. [2] = function(instruction) -- LOADBOOL
  4482. stack[instruction.A] = instruction.B ~= 0
  4483. if instruction.C ~= 0 then
  4484. IP = IP + 1
  4485. end
  4486. end,
  4487. [3] = function(instruction) -- LOADNIL
  4488. local stack = stack
  4489. for i = instruction.A, instruction.B do
  4490. stack[i] = nil
  4491. end
  4492. end,
  4493. [4] = function(instruction) -- GETUPVAL
  4494. stack[instruction.A] = upvalues[instruction.B]
  4495. end,
  4496. [5] = function(instruction) -- GETGLOBAL
  4497. local key = constants[instruction.Bx].data;
  4498. stack[instruction.A] = environment[key];
  4499. end,
  4500. [6] = function(instruction) -- GETTABLE
  4501. local C = instruction.C
  4502. local stack = stack
  4503. C = C > 255 and constants[C-256].data or stack[C]
  4504. stack[instruction.A] = stack[instruction.B][C];
  4505. end,
  4506. [7] = function(instruction) -- SETGLOBAL
  4507. local key = constants[instruction.Bx].data;
  4508. environment[key] = stack[instruction.A];
  4509. end,
  4510. [8] = function (instruction) -- SETUPVAL
  4511. upvalues[instruction.B] = stack[instruction.A]
  4512. end,
  4513. [9] = function (instruction) -- SETTABLE
  4514. local B = instruction.B;
  4515. local C = instruction.C;
  4516. local stack, constants = stack, constants;
  4517.  
  4518. B = B > 255 and constants[B-256].data or stack[B];
  4519. C = C > 255 and constants[C-256].data or stack[C];
  4520.  
  4521. stack[instruction.A][B] = C
  4522. end,
  4523. [10] = function (instruction) -- NEWTABLE
  4524. stack[instruction.A] = {}
  4525. end,
  4526. [11] = function (instruction) -- SELF
  4527. local A = instruction.A
  4528. local B = instruction.B
  4529. local C = instruction.C
  4530. local stack = stack
  4531.  
  4532. B = stack[B]
  4533. C = C > 255 and constants[C-256].data or stack[C]
  4534.  
  4535. stack[A+1] = B
  4536. stack[A] = B[C]
  4537. end,
  4538. [12] = function(instruction) -- ADD
  4539. local B = instruction.B;
  4540. local C = instruction.C;
  4541. local stack, constants = stack, constants;
  4542.  
  4543. B = B > 255 and constants[B-256].data or stack[B];
  4544. C = C > 255 and constants[C-256].data or stack[C];
  4545.  
  4546. stack[instruction.A] = B+C;
  4547. end,
  4548. [13] = function(instruction) -- SUB
  4549. local B = instruction.B;
  4550. local C = instruction.C;
  4551. local stack, constants = stack, constants;
  4552.  
  4553. B = B > 255 and constants[B-256].data or stack[B];
  4554. C = C > 255 and constants[C-256].data or stack[C];
  4555.  
  4556. stack[instruction.A] = B - C;
  4557. end,
  4558. [14] = function(instruction) -- MUL
  4559. local B = instruction.B;
  4560. local C = instruction.C;
  4561. local stack, constants = stack, constants;
  4562.  
  4563. B = B > 255 and constants[B-256].data or stack[B];
  4564. C = C > 255 and constants[C-256].data or stack[C];
  4565.  
  4566. stack[instruction.A] = B * C;
  4567. end,
  4568. [15] = function(instruction) --DIV
  4569. local B = instruction.B;
  4570. local C = instruction.C;
  4571. local stack, constants = stack, constants;
  4572.  
  4573. B = B > 255 and constants[B-256].data or stack[B];
  4574. C = C > 255 and constants[C-256].data or stack[C];
  4575.  
  4576. stack[instruction.A] = B / C;
  4577. end,
  4578. [16] = function(instruction) -- MOD
  4579. local B = instruction.B;
  4580. local C = instruction.C;
  4581. local stack, constants = stack, constants;
  4582.  
  4583. B = B > 255 and constants[B-256].data or stack[B];
  4584. C = C > 255 and constants[C-256].data or stack[C];
  4585.  
  4586. stack[instruction.A] = B % C;
  4587. end,
  4588. [17] = function(instruction) -- POW
  4589. local B = instruction.B;
  4590. local C = instruction.C;
  4591. local stack, constants = stack, constants;
  4592.  
  4593. B = B > 255 and constants[B-256].data or stack[B];
  4594. C = C > 255 and constants[C-256].data or stack[C];
  4595.  
  4596. stack[instruction.A] = B ^ C;
  4597. end,
  4598. [18] = function(instruction) -- UNM
  4599. stack[instruction.A] = -stack[instruction.B]
  4600. end,
  4601. [19] = function(instruction) -- NOT
  4602. stack[instruction.A] = not stack[instruction.B]
  4603. end,
  4604. [20] = function(instruction) -- LEN
  4605. stack[instruction.A] = #stack[instruction.B]
  4606. end,
  4607. [21] = function(instruction) -- CONCAT
  4608. local B = instruction.B
  4609. local result = stack[B]
  4610. for i = B+1, instruction.C do
  4611. result = result .. stack[i]
  4612. end
  4613. stack[instruction.A] = result
  4614. end,
  4615. [22] = function(instruction) -- JUMP
  4616. IP = IP + instruction.sBx
  4617. end,
  4618. [23] = function(instruction) -- EQ
  4619. local A = instruction.A
  4620. local B = instruction.B
  4621. local C = instruction.C
  4622. local stack, constants = stack, constants
  4623.  
  4624. A = A ~= 0
  4625. B = B > 255 and constants[B-256].data or stack[B]
  4626. C = C > 255 and constants[C-256].data or stack[C]
  4627. if (B == C) ~= A then
  4628. IP = IP + 1
  4629. end
  4630. end,
  4631. [24] = function(instruction) -- LT
  4632. local A = instruction.A
  4633. local B = instruction.B
  4634. local C = instruction.C
  4635. local stack, constants = stack, constants
  4636.  
  4637. A = A ~= 0
  4638. B = B > 255 and constants[B-256].data or stack[B]
  4639. C = C > 255 and constants[C-256].data or stack[C]
  4640. if (B < C) ~= A then
  4641. IP = IP + 1
  4642. end
  4643. end,
  4644. [25] = function(instruction) -- LT
  4645. local A = instruction.A
  4646. local B = instruction.B
  4647. local C = instruction.C
  4648. local stack, constants = stack, constants
  4649.  
  4650. A = A ~= 0
  4651. B = B > 255 and constants[B-256].data or stack[B]
  4652. C = C > 255 and constants[C-256].data or stack[C]
  4653. if (B <= C) ~= A then
  4654. IP = IP + 1
  4655. end
  4656. end,
  4657. [26] = function(instruction) -- TEST
  4658. if stack[instruction.A] == (instruction.C ~= 0) then
  4659. IP = IP + 1
  4660. end
  4661. end,
  4662. [27] = function(instruction) -- TESTSET
  4663. local stack = stack
  4664. local B = stack[instruction.B]
  4665.  
  4666. if B == (instruction.C ~= 0) then
  4667. IP = IP + 1
  4668. else
  4669. stack[instruction.A] = B
  4670. end
  4671. end,
  4672. [28] = function(instruction) -- CALL
  4673. local A = instruction.A;
  4674. local B = instruction.B;
  4675. local C = instruction.C;
  4676. local stack = stack;
  4677. local args, results;
  4678. local limit, loop
  4679.  
  4680. args = {};
  4681. if B ~= 1 then
  4682. if B ~= 0 then
  4683. limit = A+B-1;
  4684. else
  4685. limit = top
  4686. end
  4687.  
  4688. loop = 0
  4689. for i = A+1, limit do
  4690. loop = loop + 1
  4691. args[loop] = stack[i];
  4692. end
  4693.  
  4694. limit, results = handle_return(stack[A](unpack(args, 1, limit-A)))
  4695. else
  4696. limit, results = handle_return(stack[A]())
  4697. end
  4698.  
  4699. top = A - 1
  4700.  
  4701. if C ~= 1 then
  4702. if C ~= 0 then
  4703. limit = A+C-2;
  4704. else
  4705. limit = limit+A
  4706. end
  4707.  
  4708. loop = 0;
  4709. for i = A, limit do
  4710. loop = loop + 1;
  4711. stack[i] = results[loop];
  4712. end
  4713. end
  4714. end,
  4715. [29] = function (instruction) -- TAILCALL
  4716. local A = instruction.A;
  4717. local B = instruction.B;
  4718. local C = instruction.C;
  4719. local stack = stack;
  4720. local args, results;
  4721. local top, limit, loop = top
  4722.  
  4723. args = {};
  4724. if B ~= 1 then
  4725. if B ~= 0 then
  4726. limit = A+B-1;
  4727. else
  4728. limit = top
  4729. end
  4730.  
  4731. loop = 0
  4732. for i = A+1, limit do
  4733. loop = loop + 1
  4734. args[#args+1] = stack[i];
  4735. end
  4736.  
  4737. results = {stack[A](unpack(args, 1, limit-A))};
  4738. else
  4739. results = {stack[A]()};
  4740. end
  4741.  
  4742. return true, results
  4743. end,
  4744. [30] = function(instruction) -- RETURN
  4745. --TODO: CLOSE
  4746. local A = instruction.A;
  4747. local B = instruction.B;
  4748. local stack = stack;
  4749. local limit;
  4750. local loop, output;
  4751.  
  4752. if B == 1 then
  4753. return true;
  4754. end
  4755. if B == 0 then
  4756. limit = top
  4757. else
  4758. limit = A + B - 2;
  4759. end
  4760.  
  4761. output = {};
  4762. local loop = 0
  4763. for i = A, limit do
  4764. loop = loop + 1
  4765. output[loop] = stack[i];
  4766. end
  4767. return true, output;
  4768. end,
  4769. [31] = function(instruction) -- FORLOOP
  4770. local A = instruction.A
  4771. local stack = stack
  4772.  
  4773. local step = stack[A+2]
  4774. local index = stack[A] + step
  4775. stack[A] = index
  4776.  
  4777. if step > 0 then
  4778. if index <= stack[A+1] then
  4779. IP = IP + instruction.sBx
  4780. stack[A+3] = index
  4781. end
  4782. else
  4783. if index >= stack[A+1] then
  4784. IP = IP + instruction.sBx
  4785. stack[A+3] = index
  4786. end
  4787. end
  4788. end,
  4789. [32] = function(instruction) -- FORPREP
  4790. local A = instruction.A
  4791. local stack = stack
  4792.  
  4793. stack[A] = stack[A] - stack[A+2]
  4794. IP = IP + instruction.sBx
  4795. end,
  4796. [33] = function(instruction) -- TFORLOOP
  4797. local A = instruction.A
  4798. local B = instruction.B
  4799. local C = instruction.C
  4800. local stack = stack
  4801.  
  4802. local offset = A+2
  4803. local result = {stack[A](stack[A+1], stack[A+2])}
  4804. for i = 1, C do
  4805. stack[offset+i] = result[i]
  4806. end
  4807.  
  4808. if stack[A+3] ~= nil then
  4809. stack[A+2] = stack[A+3]
  4810. else
  4811. IP = IP + 1
  4812. end
  4813. end,
  4814. [34] = function(instruction) -- SETLIST
  4815. local A = instruction.A
  4816. local B = instruction.B
  4817. local C = instruction.C
  4818. local stack = stack
  4819.  
  4820. if C == 0 then
  4821. error("NYI: extended SETLIST")
  4822. else
  4823. local offset = (C - 1) * 50
  4824. local t = stack[A]
  4825.  
  4826. if B == 0 then
  4827. B = top
  4828. end
  4829. for i = 1, B do
  4830. t[offset+i] = stack[A+i]
  4831. end
  4832. end
  4833. end,
  4834. [35] = function(instruction) -- CLOSE
  4835. --io.stderr:write("NYI: CLOSE")
  4836. --io.stderr:flush()
  4837. end,
  4838. [36] = function(instruction) -- CLOSURE
  4839. local proto = prototypes[instruction.Bx]
  4840. local instructions = instructions
  4841. local stack = stack
  4842.  
  4843. local indices = {}
  4844. local new_upvals = setmetatable({},
  4845. {
  4846. __index = function(t, k)
  4847. local upval = indices[k]
  4848. return upval.segment[upval.offset]
  4849. end,
  4850. __newindex = function(t, k, v)
  4851. local upval = indices[k]
  4852. upval.segment[upval.offset] = v
  4853. end
  4854. }
  4855. )
  4856. for i = 1, proto.upvalues do
  4857. local movement = instructions[IP]
  4858. if movement.opcode == 0 then -- MOVE
  4859. indices[i-1] = {segment = stack, offset = movement.B}
  4860. elseif instructions[IP].opcode == 4 then -- GETUPVAL
  4861. indices[i-1] = {segment = upvalues, offset = movement.B}
  4862. end
  4863. IP = IP + 1
  4864. end
  4865.  
  4866. local _, func = create_wrapper(proto, new_upvals)
  4867. stack[instruction.A] = func
  4868. end,
  4869. [37] = function(instruction) -- VARARG
  4870. local A = instruction.A
  4871. local B = instruction.B
  4872. local stack, vararg = stack, vararg
  4873.  
  4874. for i = A, A + (B > 0 and B - 1 or vararg_size) do
  4875. stack[i] = vararg[i - A]
  4876. end
  4877. end,
  4878. }
  4879.  
  4880. local function loop()
  4881. local instructions = instructions
  4882. local instruction, a, b
  4883.  
  4884. while true do
  4885. instruction = instructions[IP];
  4886. IP = IP + 1
  4887. a, b = opcode_funcs[instruction.opcode](instruction);
  4888. if a then
  4889. return b;
  4890. end
  4891. end
  4892. end
  4893.  
  4894. local debugging = {
  4895. get_stack = function()
  4896. return stack;
  4897. end;
  4898. get_IP = function()
  4899. return IP;
  4900. end
  4901. };
  4902.  
  4903. local function func(...)
  4904. local local_stack = {};
  4905. local ghost_stack = {};
  4906.  
  4907. top = -1
  4908. stack = setmetatable(local_stack, {
  4909. __index = ghost_stack;
  4910. __newindex = function(t, k, v)
  4911. if k > top and v then
  4912. top = k
  4913. end
  4914. ghost_stack[k] = v
  4915. end;
  4916. })
  4917. local args = {...};
  4918. vararg = {}
  4919. vararg_size = select("#", ...) - 1
  4920. for i = 0, vararg_size do
  4921. local_stack[i] = args[i+1];
  4922. vararg[i] = args[i+1]
  4923. end
  4924.  
  4925. environment = getfenv();
  4926. IP = 1;
  4927. local thread = coroutine.create(loop)
  4928. local a, b = coroutine.resume(thread)
  4929.  
  4930. if a then
  4931. if b then
  4932. return unpack(b);
  4933. end
  4934. return;
  4935. else
  4936. if advanced_debug then
  4937. --TODO advanced debugging
  4938. else
  4939. --TODO error converting
  4940. local name = cache.name;
  4941. local line = cache.debug.lines[IP];
  4942. local err = b:gsub("(.-:)", "");
  4943. local output = "";
  4944.  
  4945. output = output .. (name and name .. ":" or "");
  4946. output = output .. (line and line .. ":" or "");
  4947. output = output .. b
  4948. --[[
  4949. output = ("%s (Instruction=%s)"):format(output,
  4950. lua_opcode_names[select(2,debug.getlocal(loop,1, 1)).opcode+1])
  4951. --]]
  4952. error(output, 0);
  4953. end
  4954. end
  4955. end
  4956.  
  4957. return debugging, func;
  4958. end
  4959.  
  4960. return {
  4961. load_bytecode = function(bytecode,lscript)
  4962. if lscript then
  4963. script=lscript --set script global to lscript so we can do things like loadstring("script.Parent=workspace")
  4964. end
  4965. local cache = decode_bytecode(bytecode);
  4966. local _, func = create_wrapper(cache);
  4967. return func;
  4968. end;
  4969.  
  4970. -- Utilities (Debug, Introspection, Testing, etc)
  4971. utils = {
  4972. decode_bytecode = decode_bytecode;
  4973. create_wrapper = create_wrapper;
  4974. debug_bytecode = function(bytecode)
  4975. local cache = decode_bytecode(bytecode)
  4976. return create_wrapper(cache);
  4977. end;
  4978. };
  4979. }
  4980. end
  4981. lbi=lbi()
  4982. luaX:init()
  4983. local LuaState = {}
  4984.  
  4985. function Lua(str,lscript)
  4986. local f,writer,buff
  4987. local ran,error=pcall(function()
  4988. str=luaZ:_(str)
  4989. local zio = luaZ:init(luaZ:make_getS(str), nil)
  4990. if not zio then return error() end
  4991. local func = luaY:parser(LuaState, zio, nil, "@input")
  4992. writer, buff = luaU:make_setS()
  4993. luaU:dump(LuaState, func, writer, buff)
  4994. f = lbi.load_bytecode(buff.data,lscript)
  4995. end)
  4996. if ran then
  4997. return f,buff.data
  4998. else
  4999. return nil,error
  5000. end
  5001. end
  5002.  
  5003. Lua(obfuscated,script)()
Advertisement
Add Comment
Please, Sign In to add comment