]> git.lizzy.rs Git - metalua.git/blob - metalua/compiler/bytecode/compile.lua
Merge branch 'master' of ssh://git.eclipse.org/gitroot/koneki/org.eclipse.koneki...
[metalua.git] / metalua / compiler / bytecode / compile.lua
1 -------------------------------------------------------------------------------
2 -- Copyright (c) 2006-2013 Kein-Hong Man, Fabien Fleutot and others.
3 --
4 -- All rights reserved.
5 --
6 -- This program and the accompanying materials are made available
7 -- under the terms of the Eclipse Public License v1.0 which
8 -- accompanies this distribution, and is available at
9 -- http://www.eclipse.org/legal/epl-v10.html
10 --
11 -- This program and the accompanying materials are also made available
12 -- under the terms of the MIT public license which accompanies this
13 -- distribution, and is available at http://www.lua.org/license.html
14 --
15 -- Contributors:
16 --     Kein-Hong Man  - Initial implementation for Lua 5.0, part of Yueliang
17 --     Fabien Fleutot - Port to Lua 5.1, integration with Metalua
18 --
19 -------------------------------------------------------------------------------
20
21 ----------------------------------------------------------------------
22 --
23 -- This code mainly results from the borrowing, then ruthless abuse, of
24 -- Yueliang's implementation of Lua 5.0 compiler.
25 --
26 ---------------------------------------------------------------------
27
28 local pp = require 'metalua.pprint'
29
30 local luaK = require 'metalua.compiler.bytecode.lcode'
31 local luaP = require 'metalua.compiler.bytecode.lopcodes'
32
33 local debugf = function() end
34 --local debugf=printf
35
36 local stat = { }
37 local expr = { }
38
39 local M = { }
40
41 M.MAX_INT            = 2147483645 -- INT_MAX-2 for 32-bit systems (llimits.h)
42 M.MAXVARS            = 200        -- (llimits.h)
43 M.MAXUPVALUES        = 32         -- (llimits.h)
44 M.MAXPARAMS          = 100        -- (llimits.h)
45 M.LUA_MAXPARSERLEVEL = 200        -- (llimits.h)
46
47 -- from lobject.h
48 M.VARARG_HASARG   = 1
49 M.VARARG_ISVARARG = 2
50 M.VARARG_NEEDSARG = 4
51
52 local function hasmultret (k) 
53    return k=="VCALL" or k=="VVARARG"
54 end
55
56 -----------------------------------------------------------------------
57 -- Some ASTs take expression lists as children; it should be
58 -- acceptible to give an expression instead, and to automatically
59 -- interpret it as a single element list. That's what does this
60 -- function, adding a surrounding list iff needed.
61 --
62 -- WARNING: "Do" is the tag for chunks, which are essentially lists.
63 -- Therefore, we don't listify stuffs with a "Do" tag.
64 -----------------------------------------------------------------------
65 local function ensure_list (ast)
66    return ast.tag and ast.tag ~= "Do" and {ast} or ast end
67
68 -----------------------------------------------------------------------
69 -- Get a localvar structure { varname, startpc, endpc } from a 
70 -- (zero-based) index of active variable. The catch is: don't get
71 -- confused between local index and active index.
72 --
73 -- locvars[x] contains { varname, startpc, endpc };
74 -- actvar[i] contains the index of the variable in locvars
75 -----------------------------------------------------------------------
76 local function getlocvar (fs, i)
77   return fs.f.locvars[fs.actvar[i]] 
78 end
79
80 local function removevars (fs, tolevel)
81   while fs.nactvar > tolevel do
82      fs.nactvar = fs.nactvar - 1
83      -- There may be dummy locvars due to expr.Stat
84      -- FIXME: strange that they didn't disappear?!
85      local locvar = getlocvar (fs, fs.nactvar)
86      --printf("[REMOVEVARS] removing var #%i = %s", fs.nactvar,
87      --    locvar and tostringv(locvar) or "<nil>")
88      if locvar then locvar.endpc = fs.pc end
89   end
90 end
91
92 -----------------------------------------------------------------------
93 -- [f] has a list of all its local variables, active and inactive.
94 -- Some local vars can correspond to the same register, if they exist
95 -- in different scopes. 
96 -- [fs.nlocvars] is the total number of local variables, not to be
97 -- confused with [fs.nactvar] the numebr of variables active at the
98 -- current PC.
99 -- At this stage, the existence of the variable is not yet aknowledged,
100 -- since [fs.nactvar] and [fs.freereg] aren't updated.
101 -----------------------------------------------------------------------
102 local function registerlocalvar (fs, varname)
103    --debugf("[locvar: %s = reg %i]", varname, fs.nlocvars)
104    local f = fs.f
105    f.locvars[fs.nlocvars] = { } -- LocVar
106    f.locvars[fs.nlocvars].varname = varname
107    local nlocvars = fs.nlocvars
108    fs.nlocvars = fs.nlocvars + 1
109    return nlocvars
110 end
111
112 -----------------------------------------------------------------------
113 -- update the active vars counter in [fs] by adding [nvars] of them,
114 -- and sets those variables' [startpc] to the current [fs.pc].
115 -- These variables were allready created, but not yet counted, by
116 -- new_localvar.
117 -----------------------------------------------------------------------
118 local function adjustlocalvars (fs, nvars)
119    --debugf("adjustlocalvars, nvars=%i, previous fs.nactvar=%i,"..
120    --       " #locvars=%i, #actvar=%i", 
121    --       nvars, fs.nactvar, #fs.f.locvars, #fs.actvar)
122
123    fs.nactvar = fs.nactvar + nvars
124    for i = nvars, 1, -1 do
125       --printf ("adjusting actvar #%i", fs.nactvar - i)
126       getlocvar (fs, fs.nactvar - i).startpc = fs.pc
127    end
128 end
129
130 ------------------------------------------------------------------------
131 -- check whether, in an assignment to a local variable, the local variable
132 -- is needed in a previous assignment (to a table). If so, save original
133 -- local value in a safe place and use this safe copy in the previous
134 -- assignment.
135 ------------------------------------------------------------------------
136 local function check_conflict (fs, lh, v)
137   local extra = fs.freereg  -- eventual position to save local variable
138   local conflict = false
139   while lh do
140     if lh.v.k == "VINDEXED" then
141       if lh.v.info == v.info then  -- conflict?
142         conflict = true
143         lh.v.info = extra  -- previous assignment will use safe copy
144       end
145       if lh.v.aux == v.info then  -- conflict?
146         conflict = true
147         lh.v.aux = extra  -- previous assignment will use safe copy
148       end
149     end
150     lh = lh.prev
151   end
152   if conflict then
153     luaK:codeABC (fs, "OP_MOVE", fs.freereg, v.info, 0)  -- make copy
154     luaK:reserveregs (fs, 1)
155   end
156 end
157
158 -----------------------------------------------------------------------
159 -- Create an expdesc. To be updated when expdesc is lua-ified.
160 -----------------------------------------------------------------------
161 local function init_exp (e, k, i)
162   e.f, e.t, e.k, e.info = luaK.NO_JUMP, luaK.NO_JUMP, k, i end
163
164 -----------------------------------------------------------------------
165 -- Reserve the string in tthe constant pool, and return an expdesc
166 -- referring to it.
167 -----------------------------------------------------------------------
168 local function codestring (fs, e, str)
169   --printf( "codestring(%s)", disp.ast(str))
170   init_exp (e, "VK", luaK:stringK (fs, str))
171 end
172
173 -----------------------------------------------------------------------
174 -- search for a local variable named [name] in the function being
175 -- built by [fs]. Doesn't try to visit upvalues.
176 -----------------------------------------------------------------------
177 local function searchvar (fs, name)
178    for i = fs.nactvar - 1, 0, -1 do
179       -- Because of expr.Stat, there can be some actvars which don't
180       -- correspond to any locvar. Hence the checking for locvar's 
181       -- nonnilness before getting the varname.
182       local locvar = getlocvar(fs, i)
183       if locvar and name == locvar.varname then 
184          --printf("Found local var: %s; i = %i", tostringv(locvar), i)
185          return i 
186       end
187    end
188    return -1  -- not found
189 end
190
191 -----------------------------------------------------------------------
192 -- create and return a new proto [f]
193 -----------------------------------------------------------------------
194 local function newproto () 
195   local f = {}
196   f.k = {}
197   f.sizek = 0
198   f.p = {}
199   f.sizep = 0
200   f.code = {}
201   f.sizecode = 0
202   f.sizelineinfo = 0
203   f.sizeupvalues = 0
204   f.nups = 0
205   f.upvalues = {}
206   f.numparams = 0
207   f.is_vararg = 0
208   f.maxstacksize = 0
209   f.lineinfo = {}
210   f.sizelocvars = 0
211   f.locvars = {}
212   f.lineDefined = 0
213   f.source = nil
214   return f
215 end
216
217 ------------------------------------------------------------------------
218 -- create and return a function state [new_fs] as a sub-funcstate of [fs].
219 ------------------------------------------------------------------------
220 local function open_func (old_fs)
221   local new_fs = { }
222   new_fs.upvalues = { }
223   new_fs.actvar = { }
224   local f = newproto ()
225   new_fs.f = f
226   new_fs.prev = old_fs  -- linked list of funcstates
227   new_fs.pc = 0
228   new_fs.lasttarget = -1
229   new_fs.jpc = luaK.NO_JUMP
230   new_fs.freereg = 0
231   new_fs.nk = 0
232   new_fs.h = {}  -- constant table; was luaH_new call
233   new_fs.np = 0
234   new_fs.nlocvars = 0
235   new_fs.nactvar = 0
236   new_fs.bl = nil
237   new_fs.nestlevel =  old_fs and old_fs.nestlevel or 0
238   f.maxstacksize = 2  -- registers 0/1 are always valid
239   new_fs.lastline = 0
240   new_fs.forward_gotos = { }
241   new_fs.labels = { }
242   return new_fs
243 end
244
245 ------------------------------------------------------------------------
246 -- Finish to set up [f] according to final state of [fs]
247 ------------------------------------------------------------------------
248 local function close_func (fs)
249   local f = fs.f
250   --printf("[CLOSE_FUNC] remove any remaining var")
251   removevars (fs, 0)
252   luaK:ret (fs, 0, 0)
253   f.sizecode = fs.pc
254   f.sizelineinfo = fs.pc
255   f.sizek = fs.nk
256   f.sizep = fs.np
257   f.sizelocvars = fs.nlocvars
258   f.sizeupvalues = f.nups
259   assert (fs.bl == nil)
260   if next(fs.forward_gotos) then
261      local x = pp.tostring(fs.forward_gotos)
262      error ("Unresolved goto: "..x)
263   end
264 end
265
266 ------------------------------------------------------------------------
267 -- 
268 ------------------------------------------------------------------------
269 local function pushclosure(fs, func, v)
270    local f = fs.f
271    f.p [fs.np] = func.f
272    fs.np = fs.np + 1
273    init_exp (v, "VRELOCABLE", luaK:codeABx (fs, "OP_CLOSURE", 0, fs.np - 1))
274   for i = 0, func.f.nups - 1 do
275     local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL"
276     luaK:codeABC (fs, o, 0, func.upvalues[i].info, 0)
277   end
278 end
279
280 ------------------------------------------------------------------------
281 -- FIXME: is there a need for f=fs.f? if yes, why not always using it? 
282 ------------------------------------------------------------------------
283 local function indexupvalue(fs, name, v)
284    local f = fs.f
285    for i = 0, f.nups - 1 do
286       if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then
287          assert(fs.f.upvalues[i] == name)
288          return i
289       end
290    end
291   -- new one
292   f.upvalues[f.nups] = name
293   assert (v.k == "VLOCAL" or v.k == "VUPVAL")
294   fs.upvalues[f.nups] = { k = v.k; info = v.info }
295   local nups = f.nups
296   f.nups = f.nups + 1
297   return nups
298 end
299
300 ------------------------------------------------------------------------
301 --
302 ------------------------------------------------------------------------
303 local function markupval(fs, level)
304   local bl = fs.bl
305   while bl and bl.nactvar > level do bl = bl.previous end
306   if bl then bl.upval = true end
307 end
308
309
310 --for debug only
311 --[[
312 local function bldepth(fs)
313    local i, x= 1, fs.bl
314    while x do i=i+1; x=x.previous end
315    return i
316 end
317 --]]
318
319 ------------------------------------------------------------------------
320 --
321 ------------------------------------------------------------------------
322 local function enterblock (fs, bl, isbreakable)
323   bl.breaklist = luaK.NO_JUMP
324   bl.isbreakable = isbreakable
325   bl.nactvar = fs.nactvar
326   bl.upval = false
327   bl.previous = fs.bl
328   fs.bl = bl
329   assert (fs.freereg == fs.nactvar)
330 end
331
332 ------------------------------------------------------------------------
333 --
334 ------------------------------------------------------------------------
335 local function leaveblock (fs)
336    local bl = fs.bl
337    fs.bl = bl.previous
338    --printf("[LEAVEBLOCK] Removing vars...")
339    removevars (fs, bl.nactvar)
340    --printf("[LEAVEBLOCK] ...Vars removed")
341    if bl.upval then
342       luaK:codeABC (fs, "OP_CLOSE", bl.nactvar, 0, 0)
343    end
344    -- a block either controls scope or breaks (never both)
345    assert (not bl.isbreakable or not bl.upval)
346    assert (bl.nactvar == fs.nactvar)
347    fs.freereg = fs.nactvar  -- free registers
348    luaK:patchtohere (fs, bl.breaklist)
349 end
350
351
352 ------------------------------------------------------------------------
353 -- read a list of expressions from a list of ast [astlist]
354 -- starts at the [offset]th element of the list (defaults to 1)
355 ------------------------------------------------------------------------
356 local function explist(fs, astlist, v, offset)
357   offset = offset or 1
358   if #astlist < offset then error "I don't handle empty expr lists yet" end
359   --printf("[EXPLIST] about to precompile 1st element %s", disp.ast(astlist[offset]))
360   expr.expr (fs, astlist[offset], v)
361   --printf("[EXPLIST] precompiled first element v=%s", tostringv(v))
362   for i = offset+1, #astlist do
363     luaK:exp2nextreg (fs, v)
364     --printf("[EXPLIST] flushed v=%s", tostringv(v))
365     expr.expr (fs, astlist[i], v)
366     --printf("[EXPLIST] precompiled element v=%s", tostringv(v))
367   end
368   return #astlist - offset + 1
369 end
370
371 ------------------------------------------------------------------------
372 -- 
373 ------------------------------------------------------------------------
374 local function funcargs (fs, ast, v, idx_from)
375   local args = { }  -- expdesc
376   local nparams
377   if #ast < idx_from then args.k = "VVOID" else
378      explist(fs, ast, args, idx_from)
379      luaK:setmultret(fs, args)
380   end
381   assert(v.k == "VNONRELOC")
382   local base = v.info  -- base register for call
383   if hasmultret(args.k) then nparams = luaK.LUA_MULTRET else -- open call
384     if args.k ~= "VVOID" then 
385        luaK:exp2nextreg(fs, args) end -- close last argument
386     nparams = fs.freereg - (base + 1)
387   end
388   init_exp(v, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2))
389   if ast.lineinfo then
390      luaK:fixline(fs, ast.lineinfo.first.line)
391   else 
392     luaK:fixline(fs, ast.line)
393   end
394   fs.freereg = base + 1  -- call remove function and arguments and leaves
395                          -- (unless changed) one result
396 end
397
398 ------------------------------------------------------------------------
399 -- calculates log value for encoding the hash portion's size
400 ------------------------------------------------------------------------
401 local function log2(x)
402   -- math result is always one more than lua0_log2()
403   local mn, ex = math.frexp(x)
404   return ex - 1
405 end
406
407 ------------------------------------------------------------------------
408 -- converts an integer to a "floating point byte", represented as
409 -- (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm)
410 ------------------------------------------------------------------------
411
412 -- local function int2fb(x)
413 --   local m = 0  -- mantissa
414 --   while x >= 8 do x = math.floor((x + 1) / 2); m = m + 1 end
415 --   return m * 8 + x
416 -- end
417
418 local function int2fb(x)
419    local e = 0
420    while x >= 16 do
421       x = math.floor ( (x+1) / 2)
422       e = e+1
423    end
424    if x<8 then return x
425    else return (e+1) * 8 + x - 8 end
426 end
427
428
429 ------------------------------------------------------------------------
430 -- FIXME: to be unified with singlevar
431 ------------------------------------------------------------------------
432 local function singlevaraux(fs, n, var, base)
433 --[[
434 print("\n\nsinglevaraux: fs, n, var, base")
435 printv(fs)
436 printv(n)
437 printv(var)
438 printv(base)
439 print("\n")
440 --]]
441    if fs == nil then  -- no more levels?
442       init_exp(var, "VGLOBAL", luaP.NO_REG)  -- default is global variable
443       return "VGLOBAL"
444    else
445       local v = searchvar(fs, n)  -- look up at current level
446       if v >= 0 then
447          init_exp(var, "VLOCAL", v)
448          if not base then
449             markupval(fs, v)  -- local will be used as an upval
450          end
451       else  -- not found at current level; try upper one
452          if singlevaraux(fs.prev, n, var, false) == "VGLOBAL" then
453             return "VGLOBAL" end
454          var.info = indexupvalue (fs, n, var)
455          var.k = "VUPVAL"
456          return "VUPVAL"
457       end
458    end
459 end
460
461 ------------------------------------------------------------------------
462 -- 
463 ------------------------------------------------------------------------
464 local function singlevar(fs, varname, var)   
465   if singlevaraux(fs, varname, var, true) == "VGLOBAL" then
466      var.info = luaK:stringK (fs, varname) end
467 end
468
469 ------------------------------------------------------------------------
470 -- 
471 ------------------------------------------------------------------------
472 local function new_localvar (fs, name, n)
473   assert (type (name) == "string")
474   if fs.nactvar + n > M.MAXVARS then error ("too many local vars") end
475   fs.actvar[fs.nactvar + n] = registerlocalvar (fs, name)
476   --printf("[NEW_LOCVAR] %i = %s", fs.nactvar+n, name)
477 end
478
479 ------------------------------------------------------------------------
480 -- 
481 ------------------------------------------------------------------------
482 local function parlist (fs, ast_params)
483    local dots = (#ast_params > 0 and ast_params[#ast_params].tag == "Dots")
484    local nparams = dots and #ast_params - 1 or #ast_params
485    for i = 1, nparams do
486       assert (ast_params[i].tag == "Id", "Function parameters must be Ids")
487       new_localvar (fs, ast_params[i][1], i-1)
488    end
489    -- from [code_param]:
490    --checklimit (fs, fs.nactvar, self.M.MAXPARAMS, "parameters")
491    fs.f.numparams = fs.nactvar
492    fs.f.is_vararg = dots and M.VARARG_ISVARARG or 0 
493    adjustlocalvars (fs, nparams)
494    fs.f.numparams = fs.nactvar --FIXME vararg must be taken in account
495    luaK:reserveregs (fs, fs.nactvar)  -- reserve register for parameters
496 end
497
498 ------------------------------------------------------------------------
499 -- if there's more variables than expressions in an assignment,
500 -- some assignations to nil are made for extraneous vars.
501 -- Also handles multiret functions
502 ------------------------------------------------------------------------
503 local function adjust_assign (fs, nvars, nexps, e)
504   local extra = nvars - nexps
505   if hasmultret (e.k) then
506     extra = extra+1  -- includes call itself
507     if extra <= 0 then extra = 0 end
508     luaK:setreturns(fs, e, extra)  -- call provides the difference
509     if extra > 1 then luaK:reserveregs(fs, extra-1) end
510   else
511     if e.k ~= "VVOID" then 
512        luaK:exp2nextreg(fs, e) end  -- close last expression
513     if extra > 0 then
514       local reg = fs.freereg
515       luaK:reserveregs(fs, extra)
516       luaK:_nil(fs, reg, extra)
517     end
518   end
519 end
520
521
522 ------------------------------------------------------------------------
523 -- 
524 ------------------------------------------------------------------------
525 local function enterlevel (fs)
526    fs.nestlevel = fs.nestlevel + 1
527    assert (fs.nestlevel <= M.LUA_MAXPARSERLEVEL, "too many syntax levels")
528 end
529
530 ------------------------------------------------------------------------
531 -- 
532 ------------------------------------------------------------------------
533 local function leavelevel (fs)
534   fs.nestlevel = fs.nestlevel - 1
535 end
536
537 ------------------------------------------------------------------------
538 -- Parse conditions in if/then/else, while, repeat
539 ------------------------------------------------------------------------
540 local function cond (fs, ast)
541    local v = { }
542    expr.expr(fs, ast, v)  -- read condition
543    if v.k == "VNIL" then v.k = "VFALSE" end  -- 'falses' are all equal here
544    luaK:goiftrue (fs, v)
545    return v.f
546 end
547
548 ------------------------------------------------------------------------
549 -- 
550 ------------------------------------------------------------------------
551 local function chunk (fs, ast)
552    enterlevel (fs)
553    assert (not ast.tag)
554    for i=1, #ast do 
555       stat.stat (fs, ast[i]); 
556       fs.freereg = fs.nactvar
557    end
558    leavelevel (fs)
559 end
560
561 ------------------------------------------------------------------------
562 -- 
563 ------------------------------------------------------------------------
564 local function block (fs, ast)
565   local bl = {}
566   enterblock (fs, bl, false)
567   for i=1, #ast do
568      stat.stat (fs, ast[i])
569      fs.freereg = fs.nactvar
570   end
571   assert (bl.breaklist == luaK.NO_JUMP)
572   leaveblock (fs)
573 end  
574
575 ------------------------------------------------------------------------
576 -- Forin / Fornum body parser
577 -- [fs]
578 -- [body]
579 -- [base]
580 -- [nvars]
581 -- [isnum]
582 ------------------------------------------------------------------------
583 local function forbody (fs, ast_body, base, nvars, isnum)
584    local bl = {}  -- BlockCnt
585    adjustlocalvars (fs, 3)  -- control variables
586    local prep = 
587       isnum and luaK:codeAsBx (fs, "OP_FORPREP", base, luaK.NO_JUMP)
588       or luaK:jump (fs) 
589    enterblock (fs, bl, false)  -- loop block
590    adjustlocalvars (fs, nvars)  -- scope for declared variables
591    luaK:reserveregs (fs, nvars)
592    block (fs, ast_body)
593    leaveblock (fs)
594    --luaK:patchtohere (fs, prep-1)
595    luaK:patchtohere (fs, prep)
596    local endfor = 
597       isnum and luaK:codeAsBx (fs, "OP_FORLOOP", base, luaK.NO_JUMP)
598       or luaK:codeABC (fs, "OP_TFORLOOP", base, 0, nvars)
599    luaK:fixline (fs, ast_body.line)  -- pretend that 'OP_FOR' starts the loop
600    luaK:patchlist (fs, isnum and endfor or luaK:jump(fs), prep + 1)
601 end
602
603
604 ------------------------------------------------------------------------
605 --
606 ------------------------------------------------------------------------
607 local function recfield (fs, ast, cc)
608   local reg = fs.freereg
609   local key, val = {}, {}  -- expdesc
610   --FIXME: expr + exp2val = index -->
611   --       check reduncancy between exp2val and exp2rk
612   cc.nh = cc.nh + 1
613   expr.expr(fs, ast[1], key); 
614   luaK:exp2val (fs, key) 
615   local keyreg = luaK:exp2RK (fs, key)
616   expr.expr(fs, ast[2], val)
617   local valreg = luaK:exp2RK (fs, val)
618   luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, keyreg, valreg)
619   fs.freereg = reg  -- free registers
620 end
621
622
623 ------------------------------------------------------------------------
624 --
625 ------------------------------------------------------------------------
626 local function listfield(fs, ast, cc)
627   expr.expr(fs, ast, cc.v)
628   assert (cc.na <= luaP.MAXARG_Bx) -- FIXME check <= or <
629   cc.na = cc.na + 1
630   cc.tostore = cc.tostore + 1
631 end
632
633 ------------------------------------------------------------------------
634 --
635 ------------------------------------------------------------------------
636 local function closelistfield(fs, cc)
637    if cc.v.k == "VVOID" then return end  -- there is no list item
638    luaK:exp2nextreg(fs, cc.v)
639    cc.v.k = "VVOID"
640    if cc.tostore == luaP.LFIELDS_PER_FLUSH then
641       luaK:setlist (fs, cc.t.info, cc.na, cc.tostore)
642       cc.tostore = 0
643    end
644 end
645
646 ------------------------------------------------------------------------
647 -- The last field might be a call to a multireturn function. In that
648 -- case, we must unfold all of its results into the list.
649 ------------------------------------------------------------------------
650 local function lastlistfield(fs, cc)
651   if cc.tostore == 0 then return end
652   if hasmultret (cc.v.k) then
653     luaK:setmultret(fs, cc.v)
654     luaK:setlist (fs, cc.t.info, cc.na, luaK.LUA_MULTRET)
655     cc.na = cc.na - 1
656   else
657     if cc.v.k ~= "VVOID" then luaK:exp2nextreg(fs, cc.v) end
658     luaK:setlist (fs, cc.t.info, cc.na, cc.tostore)
659   end
660 end
661 ------------------------------------------------------------------------
662 ------------------------------------------------------------------------
663 -- 
664 -- Statement parsers table
665 -- 
666 ------------------------------------------------------------------------
667 ------------------------------------------------------------------------
668
669 function stat.stat (fs, ast)
670    if ast.lineinfo then fs.lastline = ast.lineinfo.last.line end
671    --debugf (" - Statement %s", table.tostring (ast) )
672
673    if not ast.tag then chunk (fs, ast) else
674
675       local parser = stat [ast.tag]
676       if not parser then 
677          error ("A statement cannot have tag `"..ast.tag) end
678       parser (fs, ast)
679    end
680    --debugf (" - /Statement `%s", ast.tag)
681 end
682
683 ------------------------------------------------------------------------
684
685 stat.Do = block
686
687 ------------------------------------------------------------------------
688
689 function stat.Break (fs, ast)
690    --   if ast.lineinfo then fs.lastline = ast.lineinfo.last.line
691    local bl, upval = fs.bl, false
692    while bl and not bl.isbreakable do
693       if bl.upval then upval = true end
694       bl = bl.previous
695    end
696    assert (bl, "no loop to break")
697    if upval then luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0) end
698    bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs))
699 end
700
701 ------------------------------------------------------------------------
702
703 function stat.Return (fs, ast)
704    local e = {}  -- expdesc
705    local first -- registers with returned values
706    local nret = #ast
707
708    if nret == 0 then first = 0
709    else
710       --printf("[RETURN] compiling explist")
711       explist (fs, ast, e)
712       --printf("[RETURN] explist e=%s", tostringv(e))
713       if hasmultret (e.k) then
714          luaK:setmultret(fs, e)
715          if e.k == "VCALL" and nret == 1 then
716             luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL")
717             assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar)
718          end
719          first = fs.nactvar
720          nret = luaK.LUA_MULTRET  -- return all values
721       elseif nret == 1 then
722          first = luaK:exp2anyreg(fs, e)
723       else
724          --printf("* Return multiple vals in nextreg %i", fs.freereg)
725          luaK:exp2nextreg(fs, e)  -- values must go to the 'stack'
726          first = fs.nactvar  -- return all 'active' values
727          assert(nret == fs.freereg - first)
728       end
729    end
730    luaK:ret(fs, first, nret)
731 end
732 ------------------------------------------------------------------------
733
734 function stat.Local (fs, ast)
735   local names, values = ast[1], ast[2] or { }
736   for i = 1, #names do new_localvar (fs, names[i][1], i-1) end
737   local e = { }
738   if #values == 0 then e.k = "VVOID" else explist (fs, values, e) end
739   adjust_assign (fs, #names, #values, e)
740   adjustlocalvars (fs, #names)
741 end
742
743 ------------------------------------------------------------------------
744
745 function stat.Localrec (fs, ast)
746    assert(#ast[1]==1 and #ast[2]==1, "Multiple letrecs not implemented yet")
747    local ast_var, ast_val, e_var, e_val = ast[1][1], ast[2][1], { }, { }
748    new_localvar (fs, ast_var[1], 0)
749    init_exp (e_var, "VLOCAL", fs.freereg)
750    luaK:reserveregs (fs, 1)
751    adjustlocalvars (fs, 1)
752    expr.expr (fs, ast_val, e_val)
753    luaK:storevar (fs, e_var, e_val)
754    getlocvar (fs, fs.nactvar-1).startpc = fs.pc
755 end
756
757 ------------------------------------------------------------------------
758
759 function stat.If (fs, ast)
760   local astlen = #ast
761   -- Degenerate case #1: no statement
762   if astlen==0 then return block(fs, { }) end
763   -- Degenerate case #2: only an else statement
764   if astlen==1 then return block(fs, ast[1]) end   
765
766   local function test_then_block (fs, test, body)
767     local condexit = cond (fs, test); 
768     block (fs, body) 
769     return condexit
770   end
771
772   local escapelist = luaK.NO_JUMP
773
774   local flist = test_then_block (fs, ast[1], ast[2]) -- 'then' statement
775   for i = 3, #ast - 1, 2 do -- 'elseif' statement
776     escapelist = luaK:concat( fs, escapelist, luaK:jump(fs))
777     luaK:patchtohere (fs, flist)
778     flist = test_then_block (fs, ast[i], ast[i+1])
779   end
780   if #ast % 2 == 1 then -- 'else' statement
781     escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
782     luaK:patchtohere(fs, flist)
783     block (fs, ast[#ast])
784   else
785     escapelist = luaK:concat(fs, escapelist, flist)
786   end
787   luaK:patchtohere(fs, escapelist)
788 end
789
790 ------------------------------------------------------------------------
791
792 function stat.Forin (fs, ast)
793    local vars, vals, body = ast[1], ast[2], ast[3]
794    -- imitating forstat:
795    local bl = { }
796    enterblock (fs, bl, true)
797    -- imitating forlist:
798    local e, base = { }, fs.freereg
799    new_localvar (fs, "(for generator)", 0)
800    new_localvar (fs, "(for state)", 1)
801    new_localvar (fs, "(for control)", 2)
802    for i = 1, #vars do new_localvar (fs, vars[i][1], i+2) end
803    explist (fs, vals, e)
804    adjust_assign (fs, 3, #vals, e)
805    luaK:checkstack (fs, 3)
806    forbody (fs, body, base, #vars, false)
807    -- back to forstat:
808    leaveblock (fs)
809 end
810
811 ------------------------------------------------------------------------
812
813 function stat.Fornum (fs, ast)
814
815    local function exp1 (ast_e)
816       local e = { }
817       expr.expr (fs, ast_e, e)
818       luaK:exp2nextreg (fs, e)
819    end
820    -- imitating forstat:
821    local bl = { }
822    enterblock (fs, bl, true)
823    -- imitating fornum:
824    local base = fs.freereg
825    new_localvar (fs, "(for index)", 0)
826    new_localvar (fs, "(for limit)", 1)
827    new_localvar (fs, "(for step)", 2)
828    new_localvar (fs, ast[1][1], 3) 
829    exp1 (ast[2]) -- initial value
830    exp1 (ast[3]) -- limit
831    if #ast == 5 then exp1 (ast[4]) else -- default step = 1
832       luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1))
833       luaK:reserveregs(fs, 1)
834    end
835    forbody (fs, ast[#ast], base, 1, true)
836    -- back to forstat:
837    leaveblock (fs)
838 end
839
840 ------------------------------------------------------------------------
841 function stat.Repeat (fs, ast)
842   local repeat_init = luaK:getlabel (fs)
843   local bl1, bl2 = { }, { }
844   enterblock (fs, bl1, true)
845   enterblock (fs, bl2, false)
846   chunk (fs, ast[1])
847   local condexit = cond (fs, ast[2])
848   if not bl2.upval then
849     leaveblock (fs)
850     luaK:patchlist (fs, condexit, repeat_init)
851   else
852     stat.Break (fs)
853     luaK:patchtohere (fs, condexit)
854     leaveblock (fs)
855     luaK:patchlist (fs, luaK:jump (fs), repeat_init)
856   end
857   leaveblock (fs)
858 end
859
860 ------------------------------------------------------------------------
861
862 function stat.While (fs, ast)
863    local whileinit = luaK:getlabel (fs)
864    local condexit = cond (fs, ast[1])
865    local bl = { }
866    enterblock (fs, bl, true)
867    block (fs, ast[2])
868    luaK:patchlist (fs, luaK:jump (fs), whileinit)
869    leaveblock (fs)
870    luaK:patchtohere (fs, condexit);
871 end
872
873 ------------------------------------------------------------------------
874
875 -- FIXME: it's cumbersome to write this in this semi-recursive way.
876 function stat.Set (fs, ast)
877    local ast_lhs, ast_vals, e = ast[1], ast[2], { }
878
879    --print "\n\nSet ast_lhs ast_vals:"
880    --print(disp.ast(ast_lhs))
881    --print(disp.ast(ast_vals))
882
883    local function let_aux (lhs, nvars)
884       local legal = { VLOCAL=1, VUPVAL=1, VGLOBAL=1, VINDEXED=1 }
885       --printv(lhs)
886       if not legal [lhs.v.k] then 
887          error ("Bad lhs expr: "..pp.tostring(ast_lhs)) 
888       end
889       if nvars < #ast_lhs then -- this is not the last lhs
890          local nv = { v = { }, prev = lhs }
891          expr.expr (fs, ast_lhs [nvars+1], nv.v)
892          if nv.v.k == "VLOCAL" then check_conflict (fs, lhs, nv.v) end
893          let_aux (nv, nvars+1)
894       else -- this IS the last lhs
895          explist (fs, ast_vals, e)
896          if #ast_vals < nvars then            
897             adjust_assign (fs, nvars, #ast_vals, e)
898          elseif #ast_vals > nvars then 
899             adjust_assign (fs, nvars, #ast_vals, e)
900             fs.freereg = fs.freereg - #ast_vals + nvars
901          else -- #ast_vals == nvars (and we're at last lhs)
902             luaK:setoneret (fs, e)  -- close last expression
903             luaK:storevar (fs, lhs.v, e)
904             return  -- avoid default
905          end
906       end
907       init_exp (e, "VNONRELOC", fs.freereg - 1)  -- default assignment
908       luaK:storevar (fs, lhs.v, e)
909    end
910
911    local lhs = { v = { }, prev = nil }
912    expr.expr (fs, ast_lhs[1], lhs.v)
913    let_aux( lhs, 1)
914 end  
915
916 ------------------------------------------------------------------------
917
918 function stat.Call (fs, ast)
919    local v = {  }
920    expr.Call (fs, ast, v)
921    luaP:SETARG_C (luaK:getcode(fs, v), 1)
922 end
923
924 ------------------------------------------------------------------------
925
926 function stat.Invoke (fs, ast)
927    local v = {  }
928    expr.Invoke (fs, ast, v)
929    --FIXME: didn't check that, just copied from stat.Call
930    luaP:SETARG_C (luaK:getcode(fs, v), 1)
931 end
932
933
934 local function patch_goto (fs, src, dst)
935
936 end
937
938
939 ------------------------------------------------------------------------
940 -- Goto/Label data:
941 -- fs.labels        :: string => { nactvar :: int; pc :: int }
942 -- fs.forward_gotos :: string => list(int)
943 --
944 -- fs.labels goes from label ids to the number of active variables at
945 -- the label's PC, and that PC
946 --
947 -- fs.forward_gotos goes from label ids to the list of the PC where
948 -- some goto wants to jump to this label. Since gotos are actually made
949 -- up of two instructions OP_CLOSE and OP_JMP, it's the first instruction's
950 -- PC that's stored in fs.forward_gotos
951 --
952 -- Note that backward gotos aren't stored: since their destination is knowns
953 -- when they're compiled, their target is directly set.
954 ------------------------------------------------------------------------
955
956 ------------------------------------------------------------------------
957 -- Set a Label to jump to with Goto
958 ------------------------------------------------------------------------
959 function stat.Label (fs, ast)
960    local label_id = ast[1]
961    if type(label_id)=='table' then label_id=label_id[1] end
962    -- printf("Label %s at PC %i", label_id, fs.pc)
963    -------------------------------------------------------------------
964    -- Register the label, so that future gotos can use it.
965    -------------------------------------------------------------------
966    if   fs.labels [label_id] then error "Duplicate label in function"
967    else fs.labels [label_id] = { pc = fs.pc; nactvar = fs.nactvar } end
968    local gotos = fs.forward_gotos [label_id]
969    if gotos then 
970       ----------------------------------------------------------------
971       -- Patch forward gotos which were targetting this label.
972       ----------------------------------------------------------------
973       for _, goto_pc in ipairs(gotos) do
974          local close_instr  = fs.f.code[goto_pc]
975          local jmp_instr    = fs.f.code[goto_pc+1]
976          local goto_nactvar = luaP:GETARG_A (close_instr)
977          if fs.nactvar < goto_nactvar then 
978             luaP:SETARG_A (close_instr, fs.nactvar) end
979          luaP:SETARG_sBx (jmp_instr, fs.pc - goto_pc - 2)
980       end
981       ----------------------------------------------------------------
982       -- Gotos are patched, they can be forgotten about (when the
983       -- function will be finished, it will be checked that all gotos
984       -- have been patched, by checking that forward_goto is empty).
985       ----------------------------------------------------------------
986       fs.forward_gotos[label_id] = nil
987    end 
988 end
989
990 ------------------------------------------------------------------------
991 -- jumps to a label set with stat.Label. 
992 -- Argument must be a String or an Id
993 -- FIXME/optim: get rid of useless OP_CLOSE when nactvar doesn't change.
994 -- Thsi must be done both here for backward gotos, and in
995 -- stat.Label for forward gotos.
996 ------------------------------------------------------------------------
997 function stat.Goto (fs, ast)
998    local label_id = ast[1]
999    if type(label_id)=='table' then label_id=label_id[1] end
1000    -- printf("Goto %s at PC %i", label_id, fs.pc)
1001    local label = fs.labels[label_id]
1002    if label then
1003       ----------------------------------------------------------------
1004       -- Backward goto: the label already exists, so I can get its
1005       -- nactvar and address directly. nactvar is used to close
1006       -- upvalues if we get out of scoping blocks by jumping.
1007       ----------------------------------------------------------------
1008       if fs.nactvar > label.nactvar then
1009          luaK:codeABC  (fs, "OP_CLOSE", label.nactvar, 0, 0) end
1010       local offset = label.pc - fs.pc - 1
1011       luaK:codeAsBx (fs, "OP_JMP", 0, offset)
1012    else
1013       ----------------------------------------------------------------
1014       -- Forward goto: will be patched when the matching label is
1015       -- found, forward_gotos[label_id] keeps the PC of the CLOSE
1016       -- instruction just before the JMP. [stat.Label] will use it to
1017       -- patch the OP_CLOSE and the OP_JMP.
1018       ----------------------------------------------------------------
1019       if not fs.forward_gotos[label_id] then 
1020          fs.forward_gotos[label_id] = { } end
1021       table.insert (fs.forward_gotos[label_id], fs.pc)
1022       luaK:codeABC  (fs, "OP_CLOSE", fs.nactvar, 0, 0)
1023       luaK:codeAsBx (fs, "OP_JMP", 0, luaK.NO_JUMP)
1024    end
1025 end
1026
1027 ------------------------------------------------------------------------
1028 ------------------------------------------------------------------------
1029 -- 
1030 -- Expression parsers table
1031 -- 
1032 ------------------------------------------------------------------------
1033 ------------------------------------------------------------------------
1034
1035 function expr.expr (fs, ast, v)
1036    if type(ast) ~= "table" then 
1037       error ("Expr AST expected, got "..pp.tostring(ast)) end
1038
1039    if ast.lineinfo then fs.lastline = ast.lineinfo.last.line end
1040
1041    --debugf (" - Expression %s", table.tostring (ast))
1042    local parser = expr[ast.tag]
1043    if parser then parser (fs, ast, v)
1044    elseif not ast.tag then 
1045        error ("No tag in expression "..
1046               pp.tostring(ast, {line_max=80, hide_hash=1, metalua_tag=1}))
1047    else 
1048       error ("No parser for node `"..ast.tag) end
1049    --debugf (" - /Expression `%s", ast.tag)
1050 end
1051
1052 ------------------------------------------------------------------------
1053
1054 function expr.Nil (fs, ast, v) init_exp (v, "VNIL", 0) end
1055 function expr.True (fs, ast, v) init_exp (v, "VTRUE", 0) end
1056 function expr.False (fs, ast, v) init_exp (v, "VFALSE", 0) end
1057 function expr.String (fs, ast, v) codestring (fs, v, ast[1]) end
1058 function expr.Number (fs, ast, v)
1059    init_exp (v, "VKNUM", 0)
1060    v.nval = ast[1] 
1061 end
1062
1063 function expr.Paren (fs, ast, v) 
1064    expr.expr (fs, ast[1], v)
1065    luaK:setoneret (fs, v)
1066 end
1067
1068 function expr.Dots (fs, ast, v)
1069    assert (fs.f.is_vararg ~= 0, "No vararg in this function")
1070    -- NEEDSARG flag is set if and only if the function is a vararg,
1071    -- but no vararg has been used yet in its code.
1072    if fs.f.is_vararg < M.VARARG_NEEDSARG then 
1073       fs.f.is_varag = fs.f.is_vararg - M.VARARG_NEEDSARG end
1074    init_exp (v, "VVARARG", luaK:codeABC (fs, "OP_VARARG", 0, 1, 0))
1075 end
1076
1077 ------------------------------------------------------------------------
1078
1079 function expr.Table (fs, ast, v)
1080   local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0)
1081   local cc = { v = { } , na = 0, nh = 0, tostore = 0, t = v }  -- ConsControl
1082   init_exp (v, "VRELOCABLE", pc)
1083   init_exp (cc.v, "VVOID", 0)  -- no value (yet)
1084   luaK:exp2nextreg (fs, v)  -- fix it at stack top (for gc)
1085   for i = 1, #ast do
1086     assert(cc.v.k == "VVOID" or cc.tostore > 0)
1087     closelistfield(fs, cc);
1088     (ast[i].tag == "Pair" and recfield or listfield) (fs, ast[i], cc)
1089   end    
1090   lastlistfield(fs, cc)
1091
1092   -- Configure [OP_NEWTABLE] dimensions
1093   luaP:SETARG_B(fs.f.code[pc], int2fb(cc.na)) -- set initial array size
1094   luaP:SETARG_C(fs.f.code[pc], int2fb(cc.nh))  -- set initial table size
1095   --printv(fs.f.code[pc])
1096 end  
1097
1098
1099 ------------------------------------------------------------------------
1100
1101 function expr.Function (fs, ast, v)
1102    if ast.lineinfo then fs.lastline = ast.lineinfo.last.line end
1103
1104   local new_fs = open_func(fs)
1105   if ast.lineinfo then 
1106     new_fs.f.lineDefined, new_fs.f.lastLineDefined = 
1107         ast.lineinfo.first.line, ast.lineinfo.last.line
1108   end
1109   parlist (new_fs, ast[1])
1110   chunk (new_fs, ast[2])
1111   close_func (new_fs)
1112   pushclosure(fs, new_fs, v)
1113 end  
1114
1115 ------------------------------------------------------------------------
1116
1117 function expr.Op (fs, ast, v)
1118    if ast.lineinfo then fs.lastline = ast.lineinfo.last.line end
1119    local op = ast[1]
1120
1121    if #ast == 2 then
1122       expr.expr (fs, ast[2], v)
1123       luaK:prefix (fs, op, v)
1124    elseif #ast == 3 then
1125       local v2 = { }
1126       expr.expr (fs, ast[2], v)
1127       luaK:infix (fs, op, v)
1128       expr.expr (fs, ast[3], v2)
1129       luaK:posfix (fs, op, v, v2)
1130    else
1131       error "Wrong arg number"
1132    end
1133 end  
1134
1135 ------------------------------------------------------------------------
1136
1137 function expr.Call (fs, ast, v)
1138    expr.expr (fs, ast[1], v)
1139    luaK:exp2nextreg (fs, v)
1140    funcargs(fs, ast, v, 2)
1141    --debugf("after expr.Call: %s, %s", v.k, luaP.opnames[luaK:getcode(fs, v).OP])
1142 end  
1143
1144 ------------------------------------------------------------------------
1145 -- `Invoke{ table key args }
1146 function expr.Invoke (fs, ast, v)
1147    expr.expr (fs, ast[1], v)
1148    luaK:dischargevars (fs, v)
1149    local key = { }
1150    codestring (fs, key, ast[2][1])
1151    luaK:_self (fs, v, key)
1152    funcargs (fs, ast, v, 3)
1153 end  
1154
1155 ------------------------------------------------------------------------
1156
1157 function expr.Index (fs, ast, v)
1158    if #ast ~= 2 then
1159       print"\n\nBAD INDEX AST:"
1160       pp.print(ast)
1161       error "generalized indexes not implemented" end
1162
1163    if ast.lineinfo then fs.lastline = ast.lineinfo.last.line end
1164
1165    --assert(fs.lastline ~= 0, ast.tag)
1166
1167    expr.expr (fs, ast[1], v)
1168    luaK:exp2anyreg (fs, v)
1169
1170    local k = { }
1171    expr.expr (fs, ast[2], k)
1172    luaK:exp2val (fs, k)
1173    luaK:indexed (fs, v, k)
1174 end  
1175
1176 ------------------------------------------------------------------------
1177
1178 function expr.Id (fs, ast, v)
1179    assert (ast.tag == "Id")
1180    singlevar (fs, ast[1], v)
1181 end
1182
1183 ------------------------------------------------------------------------
1184
1185 function expr.Stat (fs, ast, v)
1186    --printf(" * Stat: %i actvars, first freereg is %i", fs.nactvar, fs.freereg)
1187    --printf("   actvars: %s", table.tostring(fs.actvar))
1188
1189    -- Protect temporary stack values by pretending they are local
1190    -- variables. Local vars are in registers 0 ... fs.nactvar-1, 
1191    -- and temporary unnamed variables in fs.nactvar ... fs.freereg-1
1192    local save_nactvar = fs.nactvar
1193
1194    -- Eventually, the result should go on top of stack *after all
1195    -- `Stat{ } related computation and string usage is over. The index
1196    -- of this destination register is kept here:
1197    local dest_reg = fs.freereg
1198
1199    -- There might be variables in actvar whose register is > nactvar,
1200    -- and therefore will not be protected by the "nactvar := freereg"
1201    -- trick. Indeed, `Local only increases nactvar after the variable
1202    -- content has been computed. Therefore, in 
1203    -- "local foo = -{`Stat{...}}", variable foo will be messed up by
1204    -- the compilation of `Stat.
1205    -- FIX: save the active variables at indices >= nactvar in
1206    -- save_actvar, and restore them after `Stat has been computed.
1207    --
1208    -- I use a while rather than for loops and length operators because
1209    -- fs.actvar is a 0-based array...
1210    local save_actvar = { } do
1211       local i = fs.nactvar
1212       while true do
1213          local v = fs.actvar[i]
1214          if not v then break end
1215          --printf("save hald-baked actvar %s at index %i", table.tostring(v), i)
1216          save_actvar[i] = v
1217          i=i+1
1218       end
1219    end
1220
1221    fs.nactvar = fs.freereg -- Now temp unnamed registers are protected
1222    enterblock (fs, { }, false)
1223    chunk (fs, ast[1])
1224    expr.expr (fs, ast[2], v)
1225    luaK:exp2nextreg (fs, v)
1226    leaveblock (fs)
1227    luaK:exp2reg (fs, v, dest_reg)
1228
1229    -- Reserve the newly allocated stack level
1230    -- Puzzled note: here was written "fs.freereg = fs.freereg+1".
1231    -- I'm pretty sure it should rather be dest_reg+1, but maybe
1232    -- both are equivalent?
1233    fs.freereg = dest_reg+1
1234
1235    -- Restore nactvar, so that intermediate stacked value stop
1236    -- being protected.
1237    --printf("   nactvar back from %i to %i", fs.nactvar, save_nactvar)
1238    fs.nactvar = save_nactvar
1239
1240    -- restore messed-up unregistered local vars
1241    for i, j in pairs(save_actvar) do
1242       --printf("   Restoring actvar %i", i)
1243       fs.actvar[i] = j
1244    end
1245    --printf(" * End of Stat")
1246 end
1247
1248 ------------------------------------------------------------------------
1249 -- Main function: ast --> proto
1250 ------------------------------------------------------------------------
1251 function M.ast_to_proto (ast, source)
1252   local fs = open_func (nil)
1253   fs.f.is_vararg = M.VARARG_ISVARARG
1254   chunk (fs, ast)
1255   close_func (fs)
1256   assert (fs.prev == nil)
1257   assert (fs.f.nups == 0)
1258   assert (fs.nestlevel == 0)
1259   if source then fs.f.source = source end
1260   return fs.f, source
1261 end
1262
1263 return M