Advertisement
-----------------

:flushed:

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