Advertisement
skinkillaz

elektrosploit v2

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