Advertisement
Guest User

Untitled

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