Advertisement
ThePiary

Tutorial SS

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