• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tarantool / luajit / 9600423662

20 Jun 2024 03:31PM UTC coverage: 92.639% (+0.04%) from 92.595%
9600423662

push

github

Buristan
ci: enable UBSan for sanitizers testing workflow

Also, this patch sorts the corresponding flags in the CI workflow
alphabetically for better readability.

Relates to tarantool/tarantool#8473

Reviewed-by: Maxim Kokryashkin <m.kokryashkin@tarantool.org>
Reviewed-by: Sergey Bronnikov <sergeyb@tarantool.org>
Signed-off-by: Sergey Kaplun <skaplun@tarantool.org>
(cherry picked from commit 4ae0bfa94)

5664 of 6021 branches covered (94.07%)

Branch coverage included in aggregate %.

21620 of 23431 relevant lines covered (92.27%)

2933451.67 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.61
/src/lj_parse.c
1
/*
2
** Lua parser (source code -> bytecode).
3
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
4
**
5
** Major portions taken verbatim or adapted from the Lua interpreter.
6
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7
*/
8

9
#define lj_parse_c
10
#define LUA_CORE
11

12
#include "lj_obj.h"
13
#include "lj_gc.h"
14
#include "lj_err.h"
15
#include "lj_debug.h"
16
#include "lj_buf.h"
17
#include "lj_str.h"
18
#include "lj_tab.h"
19
#include "lj_func.h"
20
#include "lj_state.h"
21
#include "lj_bc.h"
22
#if LJ_HASFFI
23
#include "lj_ctype.h"
24
#endif
25
#include "lj_strfmt.h"
26
#include "lj_lex.h"
27
#include "lj_parse.h"
28
#include "lj_vm.h"
29
#include "lj_vmevent.h"
30
#if LJ_HASMEMPROF
31
#include "lj_memprof.h"
32
#endif
33
#if LJ_HASSYSPROF
34
#include "lj_sysprof.h"
35
#endif
36

37
/* -- Parser structures and definitions ----------------------------------- */
38

39
/* Expression kinds. */
40
typedef enum {
41
  /* Constant expressions must be first and in this order: */
42
  VKNIL,
43
  VKFALSE,
44
  VKTRUE,
45
  VKSTR,        /* sval = string value */
46
  VKNUM,        /* nval = number value */
47
  VKLAST = VKNUM,
48
  VKCDATA,        /* nval = cdata value, not treated as a constant expression */
49
  /* Non-constant expressions follow: */
50
  VLOCAL,        /* info = local register, aux = vstack index */
51
  VUPVAL,        /* info = upvalue index, aux = vstack index */
52
  VGLOBAL,        /* sval = string value */
53
  VINDEXED,        /* info = table register, aux = index reg/byte/string const */
54
  VJMP,                /* info = instruction PC */
55
  VRELOCABLE,        /* info = instruction PC */
56
  VNONRELOC,        /* info = result register */
57
  VCALL,        /* info = instruction PC, aux = base */
58
  VVOID
59
} ExpKind;
60

61
/* Expression descriptor. */
62
typedef struct ExpDesc {
63
  union {
64
    struct {
65
      uint32_t info;        /* Primary info. */
66
      uint32_t aux;        /* Secondary info. */
67
    } s;
68
    TValue nval;        /* Number value. */
69
    GCstr *sval;        /* String value. */
70
  } u;
71
  ExpKind k;
72
  BCPos t;                /* True condition jump list. */
73
  BCPos f;                /* False condition jump list. */
74
} ExpDesc;
75

76
/* Macros for expressions. */
77
#define expr_hasjump(e)                ((e)->t != (e)->f)
78

79
#define expr_isk(e)                ((e)->k <= VKLAST)
80
#define expr_isk_nojump(e)        (expr_isk(e) && !expr_hasjump(e))
81
#define expr_isnumk(e)                ((e)->k == VKNUM)
82
#define expr_isnumk_nojump(e)        (expr_isnumk(e) && !expr_hasjump(e))
83
#define expr_isstrk(e)                ((e)->k == VKSTR)
84

85
#define expr_numtv(e)                check_exp(expr_isnumk((e)), &(e)->u.nval)
86
#define expr_numberV(e)                numberVnum(expr_numtv((e)))
87

88
/* Initialize expression. */
89
static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info)
3,005,632✔
90
{
91
  e->k = k;
3,005,632✔
92
  e->u.s.info = info;
3,005,632✔
93
  e->f = e->t = NO_JMP;
3,005,632✔
94
}
146,349✔
95

96
/* Check number constant for +-0. */
97
static int expr_numiszero(ExpDesc *e)
2,916✔
98
{
99
  TValue *o = expr_numtv(e);
2,916✔
100
  return tvisint(o) ? (intV(o) == 0) : tviszero(o);
2,916✔
101
}
102

103
/* Per-function linked list of scope blocks. */
104
typedef struct FuncScope {
105
  struct FuncScope *prev;        /* Link to outer scope. */
106
  MSize vstart;                        /* Start of block-local variables. */
107
  uint8_t nactvar;                /* Number of active vars outside the scope. */
108
  uint8_t flags;                /* Scope flags. */
109
} FuncScope;
110

111
#define FSCOPE_LOOP                0x01        /* Scope is a (breakable) loop. */
112
#define FSCOPE_BREAK                0x02        /* Break used in scope. */
113
#define FSCOPE_GOLA                0x04        /* Goto or label used in scope. */
114
#define FSCOPE_UPVAL                0x08        /* Upvalue in scope. */
115
#define FSCOPE_NOCLOSE                0x10        /* Do not close upvalues. */
116

117
#define NAME_BREAK                ((GCstr *)(uintptr_t)1)
118

119
/* Index into variable stack. */
120
typedef uint16_t VarIndex;
121
#define LJ_MAX_VSTACK                (65536 - LJ_MAX_UPVAL)
122

123
/* Variable/goto/label info. */
124
#define VSTACK_VAR_RW                0x01        /* R/W variable. */
125
#define VSTACK_GOTO                0x02        /* Pending goto. */
126
#define VSTACK_LABEL                0x04        /* Label. */
127

128
/* Per-function state. */
129
typedef struct FuncState {
130
  GCtab *kt;                        /* Hash table for constants. */
131
  LexState *ls;                        /* Lexer state. */
132
  lua_State *L;                        /* Lua state. */
133
  FuncScope *bl;                /* Current scope. */
134
  struct FuncState *prev;        /* Enclosing function. */
135
  BCPos pc;                        /* Next bytecode position. */
136
  BCPos lasttarget;                /* Bytecode position of last jump target. */
137
  BCPos jpc;                        /* Pending jump list to next bytecode. */
138
  BCReg freereg;                /* First free register. */
139
  BCReg nactvar;                /* Number of active local variables. */
140
  BCReg nkn, nkgc;                /* Number of lua_Number/GCobj constants */
141
  BCLine linedefined;                /* First line of the function definition. */
142
  BCInsLine *bcbase;                /* Base of bytecode stack. */
143
  BCPos bclim;                        /* Limit of bytecode stack. */
144
  MSize vbase;                        /* Base of variable stack for this function. */
145
  uint8_t flags;                /* Prototype flags. */
146
  uint8_t numparams;                /* Number of parameters. */
147
  uint8_t framesize;                /* Fixed frame size. */
148
  uint8_t nuv;                        /* Number of upvalues */
149
  VarIndex varmap[LJ_MAX_LOCVAR];  /* Map from register to variable idx. */
150
  VarIndex uvmap[LJ_MAX_UPVAL];        /* Map from upvalue to variable idx. */
151
  VarIndex uvtmp[LJ_MAX_UPVAL];        /* Temporary upvalue map. */
152
} FuncState;
153

154
/* Binary and unary operators. ORDER OPR */
155
typedef enum BinOpr {
156
  OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,  /* ORDER ARITH */
157
  OPR_CONCAT,
158
  OPR_NE, OPR_EQ,
159
  OPR_LT, OPR_GE, OPR_LE, OPR_GT,
160
  OPR_AND, OPR_OR,
161
  OPR_NOBINOPR
162
} BinOpr;
163

164
LJ_STATIC_ASSERT((int)BC_ISGE-(int)BC_ISLT == (int)OPR_GE-(int)OPR_LT);
165
LJ_STATIC_ASSERT((int)BC_ISLE-(int)BC_ISLT == (int)OPR_LE-(int)OPR_LT);
166
LJ_STATIC_ASSERT((int)BC_ISGT-(int)BC_ISLT == (int)OPR_GT-(int)OPR_LT);
167
LJ_STATIC_ASSERT((int)BC_SUBVV-(int)BC_ADDVV == (int)OPR_SUB-(int)OPR_ADD);
168
LJ_STATIC_ASSERT((int)BC_MULVV-(int)BC_ADDVV == (int)OPR_MUL-(int)OPR_ADD);
169
LJ_STATIC_ASSERT((int)BC_DIVVV-(int)BC_ADDVV == (int)OPR_DIV-(int)OPR_ADD);
170
LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD);
171

172
#ifdef LUA_USE_ASSERT
173
#define lj_assertFS(c, ...)        (lj_assertG_(G(fs->L), (c), __VA_ARGS__))
174
#else
175
#define lj_assertFS(c, ...)        ((void)fs)
176
#endif
177

178
/* -- Error handling ------------------------------------------------------ */
179

180
LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em)
7,371✔
181
{
182
  lj_lex_error(ls, ls->tok, em);
7,371✔
183
}
184

185
LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken tok)
4,936✔
186
{
187
  lj_lex_error(ls, ls->tok, LJ_ERR_XTOKEN, lj_lex_token2str(ls, tok));
4,936✔
188
}
189

190
LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what)
191
{
192
  if (fs->linedefined == 0)
193
    lj_lex_error(fs->ls, 0, LJ_ERR_XLIMM, limit, what);
194
  else
195
    lj_lex_error(fs->ls, 0, LJ_ERR_XLIMF, fs->linedefined, limit, what);
196
}
197

198
#define checklimit(fs, v, l, m)                if ((v) >= (l)) err_limit(fs, l, m)
199
#define checklimitgt(fs, v, l, m)        if ((v) > (l)) err_limit(fs, l, m)
200
#define checkcond(ls, c, em)                { if (!(c)) err_syntax(ls, em); }
201

202
/* -- Management of constants --------------------------------------------- */
203

204
/* Return bytecode encoding for primitive constant. */
205
#define const_pri(e)                check_exp((e)->k <= VKTRUE, (e)->k)
206

207
#define tvhaskslot(o)        ((o)->u32.hi == 0)
208
#define tvkslot(o)        ((o)->u32.lo)
209

210
/* Add a number constant. */
211
static BCReg const_num(FuncState *fs, ExpDesc *e)
148,825✔
212
{
213
  lua_State *L = fs->L;
148,825✔
214
  TValue *o;
148,825✔
215
  lj_assertFS(expr_isnumk(e), "bad usage");
148,825✔
216
  o = lj_tab_set(L, fs->kt, &e->u.nval);
148,825✔
217
  if (tvhaskslot(o))
148,825✔
218
    return tvkslot(o);
3,001✔
219
  o->u64 = fs->nkn;
145,824✔
220
  return fs->nkn++;
145,824✔
221
}
222

223
/* Add a GC object constant. */
224
static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype)
805,493✔
225
{
226
  lua_State *L = fs->L;
805,493✔
227
  TValue key, *o;
805,493✔
228
  setgcV(L, &key, gc, itype);
805,493✔
229
  /* NOBARRIER: the key is new or kept alive. */
230
  o = lj_tab_set(L, fs->kt, &key);
805,493✔
231
  if (tvhaskslot(o))
805,493✔
232
    return tvkslot(o);
392,854✔
233
  o->u64 = fs->nkgc;
412,639✔
234
  return fs->nkgc++;
412,639✔
235
}
236

237
/* Add a string constant. */
238
static BCReg const_str(FuncState *fs, ExpDesc *e)
587,023✔
239
{
240
  lj_assertFS(expr_isstrk(e) || e->k == VGLOBAL, "bad usage");
587,023✔
241
  return const_gc(fs, obj2gco(e->u.sval), LJ_TSTR);
587,023✔
242
}
243

244
/* Anchor string constant to avoid GC. */
245
GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t len)
2,993,036✔
246
{
247
  /* NOBARRIER: the key is new or kept alive. */
248
  lua_State *L = ls->L;
2,993,036✔
249
  GCstr *s = lj_str_new(L, str, len);
2,993,036✔
250
  TValue *tv = lj_tab_setstr(L, ls->fs->kt, s);
2,993,036✔
251
  if (tvisnil(tv)) setboolV(tv, 1);
2,993,036✔
252
  lj_gc_check(L);
2,993,036✔
253
  return s;
2,993,036✔
254
}
255

256
#if LJ_HASFFI
257
/* Anchor cdata to avoid GC. */
258
void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd)
252✔
259
{
260
  /* NOBARRIER: the key is new or kept alive. */
261
  lua_State *L = ls->L;
252✔
262
  setcdataV(L, tv, cd);
252✔
263
  setboolV(lj_tab_set(L, ls->fs->kt, tv), 1);
252✔
264
}
252✔
265
#endif
266

267
/* -- Jump list handling -------------------------------------------------- */
268

269
/* Get next element in jump list. */
270
static BCPos jmp_next(FuncState *fs, BCPos pc)
746,396✔
271
{
272
  ptrdiff_t delta = bc_j(fs->bcbase[pc].ins);
746,396✔
273
  if ((BCPos)delta == NO_JMP)
746,396✔
274
    return NO_JMP;
275
  else
276
    return (BCPos)(((ptrdiff_t)pc+1)+delta);
76,248✔
277
}
278

279
/* Check if any of the instructions on the jump list produce no value. */
280
static int jmp_novalue(FuncState *fs, BCPos list)
281
{
282
  for (; list != NO_JMP; list = jmp_next(fs, list)) {
283
    BCIns p = fs->bcbase[list >= 1 ? list-1 : list].ins;
284
    if (!(bc_op(p) == BC_ISTC || bc_op(p) == BC_ISFC || bc_a(p) == NO_REG))
285
      return 1;
286
  }
287
  return 0;
288
}
289

290
/* Patch register of test instructions. */
291
static int jmp_patchtestreg(FuncState *fs, BCPos pc, BCReg reg)
292
{
293
  BCInsLine *ilp = &fs->bcbase[pc >= 1 ? pc-1 : pc];
294
  BCOp op = bc_op(ilp->ins);
295
  if (op == BC_ISTC || op == BC_ISFC) {
296
    if (reg != NO_REG && reg != bc_d(ilp->ins)) {
297
      setbc_a(&ilp->ins, reg);
298
    } else {  /* Nothing to store or already in the right register. */
299
      setbc_op(&ilp->ins, op+(BC_IST-BC_ISTC));
300
      setbc_a(&ilp->ins, 0);
301
    }
302
  } else if (bc_a(ilp->ins) == NO_REG) {
303
    if (reg == NO_REG) {
304
      ilp->ins = BCINS_AJ(BC_JMP, bc_a(fs->bcbase[pc].ins), 0);
305
    } else {
306
      setbc_a(&ilp->ins, reg);
307
      if (reg >= bc_a(ilp[1].ins))
308
        setbc_a(&ilp[1].ins, reg+1);
309
    }
310
  } else {
311
    return 0;  /* Cannot patch other instructions. */
312
  }
313
  return 1;
314
}
315

316
/* Drop values for all instructions on jump list. */
317
static void jmp_dropval(FuncState *fs, BCPos list)
593,852✔
318
{
319
  for (; list != NO_JMP; list = jmp_next(fs, list))
629,868✔
320
    jmp_patchtestreg(fs, list, NO_REG);
36,016✔
321
}
593,852✔
322

323
/* Patch jump instruction to target. */
324
static void jmp_patchins(FuncState *fs, BCPos pc, BCPos dest)
765,592✔
325
{
326
  BCIns *jmp = &fs->bcbase[pc].ins;
765,592✔
327
  BCPos offset = dest-(pc+1)+BCBIAS_J;
765,592✔
328
  lj_assertFS(dest != NO_JMP, "uninitialized jump target");
765,592✔
329
  if (offset > BCMAX_D)
765,592✔
330
    err_syntax(fs->ls, LJ_ERR_XJUMP);
×
331
  setbc_d(jmp, offset);
765,592✔
332
}
706,103✔
333

334
/* Append to jump list. */
335
static void jmp_append(FuncState *fs, BCPos *l1, BCPos l2)
2,101,763✔
336
{
337
  if (l2 == NO_JMP) {
2,101,763✔
338
    return;
339
  } else if (*l1 == NO_JMP) {
915,356✔
340
    *l1 = l2;
839,106✔
341
  } else {
342
    BCPos list = *l1;
343
    BCPos next;
344
    while ((next = jmp_next(fs, list)) != NO_JMP)  /* Find last element. */
80,527✔
345
      list = next;
346
    jmp_patchins(fs, list, l2);
76,250✔
347
  }
348
}
349

350
/* Patch jump list and preserve produced values. */
351
static void jmp_patchval(FuncState *fs, BCPos list, BCPos vtarget,
4,740,629✔
352
                         BCReg reg, BCPos dtarget)
353
{
354
  while (list != NO_JMP) {
4,740,629✔
355
    BCPos next = jmp_next(fs, list);
629,853✔
356
    if (jmp_patchtestreg(fs, list, reg))
629,853✔
357
      jmp_patchins(fs, list, vtarget);  /* Jump to target with value. */
73,894✔
358
    else
359
      jmp_patchins(fs, list, dtarget);  /* Jump to default target. */
5,926,441✔
360
    list = next;
361
  }
362
}
4,740,629✔
363

364
/* Jump to following instruction. Append to list of pending jumps. */
365
static void jmp_tohere(FuncState *fs, BCPos list)
724,103✔
366
{
367
  fs->lasttarget = fs->pc;
724,103✔
368
  jmp_append(fs, &fs->jpc, list);
724,103✔
369
}
311,913✔
370

371
/* Patch jump list to target. */
372
static void jmp_patch(FuncState *fs, BCPos list, BCPos target)
99,140✔
373
{
374
  if (target == fs->pc) {
99,140✔
375
    jmp_tohere(fs, list);
49,519✔
376
  } else {
377
    lj_assertFS(target < fs->pc, "bad jump target");
49,621✔
378
    jmp_patchval(fs, list, target, NO_REG, target);
49,621✔
379
  }
380
}
99,140✔
381

382
/* -- Bytecode register allocator ----------------------------------------- */
383

384
/* Bump frame size. */
385
static void bcreg_bump(FuncState *fs, BCReg n)
1,795,926✔
386
{
387
  BCReg sz = fs->freereg + n;
1,795,926✔
388
  if (sz > fs->framesize) {
1,795,926✔
389
    if (sz >= LJ_MAX_SLOTS)
263,870✔
390
      err_syntax(fs->ls, LJ_ERR_XSLOTS);
×
391
    fs->framesize = (uint8_t)sz;
263,870✔
392
  }
393
}
394

395
/* Reserve registers. */
396
static void bcreg_reserve(FuncState *fs, BCReg n)
1,794,631✔
397
{
398
  bcreg_bump(fs, n);
1,794,631✔
399
  fs->freereg += n;
1,794,631✔
400
}
1,794,631✔
401

402
/* Free register. */
403
static void bcreg_free(FuncState *fs, BCReg reg)
637,549✔
404
{
405
  if (reg >= fs->nactvar) {
637,549✔
406
    fs->freereg--;
345,284✔
407
    lj_assertFS(reg == fs->freereg, "bad regfree");
5,271✔
408
  }
409
}
410

411
/* Free register for expression. */
412
static void expr_free(FuncState *fs, ExpDesc *e)
2,104,585✔
413
{
414
  if (e->k == VNONRELOC)
2,104,585✔
415
    bcreg_free(fs, e->u.s.info);
521,968✔
416
}
417

418
/* -- Bytecode emitter ---------------------------------------------------- */
419

420
/* Emit bytecode instruction. */
421
static BCPos bcemit_INS(FuncState *fs, BCIns ins)
4,106,566✔
422
{
423
  BCPos pc = fs->pc;
4,106,566✔
424
  LexState *ls = fs->ls;
4,106,566✔
425
  jmp_patchval(fs, fs->jpc, pc, NO_REG, pc);
4,106,566✔
426
  fs->jpc = NO_JMP;
4,106,566✔
427
  if (LJ_UNLIKELY(pc >= fs->bclim)) {
4,106,566✔
428
    ptrdiff_t base = fs->bcbase - ls->bcstack;
149,948✔
429
    checklimit(fs, ls->sizebcstack, LJ_MAX_BCINS, "bytecode instructions");
149,948✔
430
    lj_mem_growvec(fs->L, ls->bcstack, ls->sizebcstack, LJ_MAX_BCINS,BCInsLine);
149,948✔
431
    fs->bclim = (BCPos)(ls->sizebcstack - base);
149,948✔
432
    fs->bcbase = ls->bcstack + base;
149,948✔
433
  }
434
  fs->bcbase[pc].ins = ins;
4,106,566✔
435
  fs->bcbase[pc].line = ls->lastline;
4,106,566✔
436
  fs->pc = pc+1;
4,106,566✔
437
  return pc;
4,106,566✔
438
}
439

440
#define bcemit_ABC(fs, o, a, b, c)        bcemit_INS(fs, BCINS_ABC(o, a, b, c))
441
#define bcemit_AD(fs, o, a, d)                bcemit_INS(fs, BCINS_AD(o, a, d))
442
#define bcemit_AJ(fs, o, a, j)                bcemit_INS(fs, BCINS_AJ(o, a, j))
443

444
#define bcptr(fs, e)                        (&(fs)->bcbase[(e)->u.s.info].ins)
445

446
/* -- Bytecode emitter for expressions ------------------------------------ */
447

448
/* Discharge non-constant expression to any register. */
449
static void expr_discharge(FuncState *fs, ExpDesc *e)
6,531,622✔
450
{
451
  BCIns ins;
6,531,622✔
452
  if (e->k == VUPVAL) {
6,531,622✔
453
    ins = BCINS_AD(BC_UGET, 0, e->u.s.info);
22,715✔
454
  } else if (e->k == VGLOBAL) {
6,508,907✔
455
    ins = BCINS_AD(BC_GGET, 0, const_str(fs, e));
287,993✔
456
  } else if (e->k == VINDEXED) {
6,220,914✔
457
    BCReg rc = e->u.s.aux;
110,310✔
458
    if ((int32_t)rc < 0) {
110,310✔
459
      ins = BCINS_ABC(BC_TGETS, 0, e->u.s.info, ~rc);
103,005✔
460
    } else if (rc > BCMAX_C) {
7,305✔
461
      ins = BCINS_ABC(BC_TGETB, 0, e->u.s.info, rc-(BCMAX_C+1));
2,034✔
462
    } else {
463
      bcreg_free(fs, rc);
5,271✔
464
      ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc);
5,271✔
465
    }
466
    bcreg_free(fs, e->u.s.info);
110,310✔
467
  } else if (e->k == VCALL) {
6,110,604✔
468
    e->u.s.info = e->u.s.aux;
244,183✔
469
    e->k = VNONRELOC;
244,183✔
470
    return;
244,183✔
471
  } else if (e->k == VLOCAL) {
5,866,421✔
472
    e->k = VNONRELOC;
472,459✔
473
    return;
472,459✔
474
  } else {
475
    return;
476
  }
477
  e->u.s.info = bcemit_INS(fs, ins);
421,018✔
478
  e->k = VRELOCABLE;
421,018✔
479
}
480

481
/* Emit bytecode to set a range of registers to nil. */
482
static void bcemit_nil(FuncState *fs, BCReg from, BCReg n)
46,685✔
483
{
484
  if (fs->pc > fs->lasttarget) {  /* No jumps to current position? */
46,685✔
485
    BCIns *ip = &fs->bcbase[fs->pc-1].ins;
30,730✔
486
    BCReg pto, pfrom = bc_a(*ip);
30,730✔
487
    switch (bc_op(*ip)) {  /* Try to merge with the previous instruction. */
30,730✔
488
    case BC_KPRI:
757✔
489
      if (bc_d(*ip) != ~LJ_TNIL) break;
757✔
490
      if (from == pfrom) {
751✔
491
        if (n == 1) return;
×
492
      } else if (from == pfrom+1) {
751✔
493
        from = pfrom;
109✔
494
        n++;
109✔
495
      } else {
496
        break;
497
      }
498
      *ip = BCINS_AD(BC_KNIL, from, from+n-1);  /* Replace KPRI. */
109✔
499
      return;
109✔
500
    case BC_KNIL:
340✔
501
      pto = bc_d(*ip);
340✔
502
      if (pfrom <= from && from <= pto+1) {  /* Can we connect both ranges? */
340✔
503
        if (from+n-1 > pto)
329✔
504
          setbc_d(ip, from+n-1);  /* Patch previous instruction range. */
327✔
505
        return;
329✔
506
      }
507
      break;
508
    default:
509
      break;
510
    }
511
  }
16,603✔
512
  /* Emit new instruction or replace old instruction. */
513
  bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) :
46,367✔
514
                          BCINS_AD(BC_KNIL, from, from+n-1));
120✔
515
}
516

517
/* Discharge an expression to a specific register. Ignore branches. */
518
static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
1,711,513✔
519
{
520
  BCIns ins;
1,711,513✔
521
  expr_discharge(fs, e);
1,711,513✔
522
  if (e->k == VKSTR) {
1,711,513✔
523
    ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e));
161,058✔
524
  } else if (e->k == VKNUM) {
1,550,455✔
525
#if LJ_DUALNUM
526
    cTValue *tv = expr_numtv(e);
527
    if (tvisint(tv) && checki16(intV(tv)))
528
      ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv));
529
    else
530
#else
531
    lua_Number n = expr_numberV(e);
555,086✔
532
    int32_t k = lj_num2int(n);
555,086✔
533
    if (checki16(k) && n == (lua_Number)k)
555,086✔
534
      ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k);
422,830✔
535
    else
536
#endif
537
      ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e));
132,256✔
538
#if LJ_HASFFI
539
  } else if (e->k == VKCDATA) {
995,369✔
540
    fs->flags |= PROTO_FFI;
252✔
541
    ins = BCINS_AD(BC_KCDATA, reg,
252✔
542
                   const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA));
543
#endif
544
  } else if (e->k == VRELOCABLE) {
995,117✔
545
    setbc_a(bcptr(fs, e), reg);
613,733✔
546
    goto noins;
613,733✔
547
  } else if (e->k == VNONRELOC) {
381,384✔
548
    if (reg == e->u.s.info)
89,845✔
549
      goto noins;
29,143✔
550
    ins = BCINS_AD(BC_MOV, reg, e->u.s.info);
60,702✔
551
  } else if (e->k == VKNIL) {
291,539✔
552
    bcemit_nil(fs, reg, 1);
29,261✔
553
    goto noins;
29,261✔
554
  } else if (e->k <= VKTRUE) {
262,278✔
555
    ins = BCINS_AD(BC_KPRI, reg, const_pri(e));
36,198✔
556
  } else {
557
    lj_assertFS(e->k == VVOID || e->k == VJMP, "bad expr type %d", e->k);
558
    return;
559
  }
560
  bcemit_INS(fs, ins);
813,296✔
561
noins:
1,485,433✔
562
  e->u.s.info = reg;
1,485,433✔
563
  e->k = VNONRELOC;
1,485,433✔
564
}
565

566
/* Forward declaration. */
567
static BCPos bcemit_jmp(FuncState *fs);
568

569
/* Discharge an expression to a specific register. */
570
static void expr_toreg(FuncState *fs, ExpDesc *e, BCReg reg)
1,672,011✔
571
{
572
  expr_toreg_nobranch(fs, e, reg);
1,672,011✔
573
  if (e->k == VJMP)
1,672,011✔
574
    jmp_append(fs, &e->t, e->u.s.info);  /* Add it to the true jump list. */
226,080✔
575
  if (expr_hasjump(e)) {  /* Discharge expression with branches. */
1,672,011✔
576
    BCPos jend, jfalse = NO_JMP, jtrue = NO_JMP;
292,221✔
577
    if (jmp_novalue(fs, e->t) || jmp_novalue(fs, e->f)) {
292,221✔
578
      BCPos jval = (e->k == VJMP) ? NO_JMP : bcemit_jmp(fs);
262,394✔
579
      jfalse = bcemit_AD(fs, BC_KPRI, reg, VKFALSE);
262,394✔
580
      bcemit_AJ(fs, BC_JMP, fs->freereg, 1);
262,394✔
581
      jtrue = bcemit_AD(fs, BC_KPRI, reg, VKTRUE);
262,394✔
582
      jmp_tohere(fs, jval);
262,394✔
583
    }
584
    jend = fs->pc;
292,221✔
585
    fs->lasttarget = jend;
292,221✔
586
    jmp_patchval(fs, e->f, jend, reg, jfalse);
292,221✔
587
    jmp_patchval(fs, e->t, jend, reg, jtrue);
292,221✔
588
  }
589
  e->f = e->t = NO_JMP;
1,672,011✔
590
  e->u.s.info = reg;
1,672,011✔
591
  e->k = VNONRELOC;
1,672,011✔
592
}
1,672,011✔
593

594
/* Discharge an expression to the next free register. */
595
static void expr_tonextreg(FuncState *fs, ExpDesc *e)
1,395,232✔
596
{
597
  expr_discharge(fs, e);
1,395,232✔
598
  expr_free(fs, e);
1,395,232✔
599
  bcreg_reserve(fs, 1);
1,395,232✔
600
  expr_toreg(fs, e, fs->freereg - 1);
1,395,232✔
601
}
1,395,232✔
602

603
/* Discharge an expression to any register. */
604
static BCReg expr_toanyreg(FuncState *fs, ExpDesc *e)
1,492,149✔
605
{
606
  expr_discharge(fs, e);
1,492,149✔
607
  if (e->k == VNONRELOC) {
1,492,149✔
608
    if (!expr_hasjump(e)) return e->u.s.info;  /* Already in a register. */
696,198✔
609
    if (e->u.s.info >= fs->nactvar) {
977✔
610
      expr_toreg(fs, e, e->u.s.info);  /* Discharge to temp. register. */
951✔
611
      return e->u.s.info;
951✔
612
    }
613
  }
614
  expr_tonextreg(fs, e);  /* Discharge to next register. */
795,977✔
615
  return e->u.s.info;
795,977✔
616
}
617

618
/* Partially discharge expression to a value. */
619
static void expr_toval(FuncState *fs, ExpDesc *e)
783,254✔
620
{
621
  if (expr_hasjump(e))
783,254✔
622
    expr_toanyreg(fs, e);
10,794✔
623
  else
624
    expr_discharge(fs, e);
772,460✔
625
}
783,254✔
626

627
/* Emit store for LHS expression. */
628
static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e)
495,334✔
629
{
630
  BCIns ins;
495,334✔
631
  if (var->k == VLOCAL) {
495,334✔
632
    fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW;
269,241✔
633
    expr_free(fs, e);
269,241✔
634
    expr_toreg(fs, e, var->u.s.info);
269,241✔
635
    return;
269,241✔
636
  } else if (var->k == VUPVAL) {
226,093✔
637
    fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW;
730✔
638
    expr_toval(fs, e);
730✔
639
    if (e->k <= VKTRUE)
730✔
640
      ins = BCINS_AD(BC_USETP, var->u.s.info, const_pri(e));
78✔
641
    else if (e->k == VKSTR)
652✔
642
      ins = BCINS_AD(BC_USETS, var->u.s.info, const_str(fs, e));
10✔
643
    else if (e->k == VKNUM)
642✔
644
      ins = BCINS_AD(BC_USETN, var->u.s.info, const_num(fs, e));
86✔
645
    else
646
      ins = BCINS_AD(BC_USETV, var->u.s.info, expr_toanyreg(fs, e));
556✔
647
  } else if (var->k == VGLOBAL) {
225,363✔
648
    BCReg ra = expr_toanyreg(fs, e);
126,223✔
649
    ins = BCINS_AD(BC_GSET, ra, const_str(fs, var));
126,223✔
650
  } else {
651
    BCReg ra, rc;
99,140✔
652
    lj_assertFS(var->k == VINDEXED, "bad expr type %d", var->k);
99,140✔
653
    ra = expr_toanyreg(fs, e);
99,140✔
654
    rc = var->u.s.aux;
99,140✔
655
    if ((int32_t)rc < 0) {
99,140✔
656
      ins = BCINS_ABC(BC_TSETS, ra, var->u.s.info, ~rc);
93,022✔
657
    } else if (rc > BCMAX_C) {
6,118✔
658
      ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1));
2,001✔
659
    } else {
660
#ifdef LUA_USE_ASSERT
661
      /* Free late alloced key reg to avoid assert on free of value reg. */
662
      /* This can only happen when called from expr_table(). */
663
      if (e->k == VNONRELOC && ra >= fs->nactvar && rc >= ra)
664
        bcreg_free(fs, rc);
665
#endif
666
      ins = BCINS_ABC(BC_TSETV, ra, var->u.s.info, rc);
4,117✔
667
    }
668
  }
669
  bcemit_INS(fs, ins);
226,093✔
670
  expr_free(fs, e);
226,093✔
671
}
672

673
/* Emit method lookup expression. */
674
static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key)
8,409✔
675
{
676
  BCReg idx, func, obj = expr_toanyreg(fs, e);
8,409✔
677
  expr_free(fs, e);
8,409✔
678
  func = fs->freereg;
8,409✔
679
  bcemit_AD(fs, BC_MOV, func+1+LJ_FR2, obj);  /* Copy object to 1st argument. */
8,409✔
680
  lj_assertFS(expr_isstrk(key), "bad usage");
8,409✔
681
  idx = const_str(fs, key);
8,409✔
682
  if (idx <= BCMAX_C) {
8,409✔
683
    bcreg_reserve(fs, 2+LJ_FR2);
8,403✔
684
    bcemit_ABC(fs, BC_TGETS, func, obj, idx);
8,403✔
685
  } else {
686
    bcreg_reserve(fs, 3+LJ_FR2);
6✔
687
    bcemit_AD(fs, BC_KSTR, func+2+LJ_FR2, idx);
6✔
688
    bcemit_ABC(fs, BC_TGETV, func, obj, func+2+LJ_FR2);
6✔
689
    fs->freereg--;
6✔
690
  }
691
  e->u.s.info = func;
8,409✔
692
  e->k = VNONRELOC;
8,409✔
693
}
8,409✔
694

695
/* -- Bytecode emitter for branches --------------------------------------- */
696

697
/* Emit unconditional branch. */
698
static BCPos bcemit_jmp(FuncState *fs)
630,302✔
699
{
700
  BCPos jpc = fs->jpc;
630,302✔
701
  BCPos j = fs->pc - 1;
630,302✔
702
  BCIns *ip = &fs->bcbase[j].ins;
630,302✔
703
  fs->jpc = NO_JMP;
630,302✔
704
  if ((int32_t)j >= (int32_t)fs->lasttarget && bc_op(*ip) == BC_UCLO) {
630,302✔
705
    setbc_j(ip, NO_JMP);
43✔
706
    fs->lasttarget = j+1;
43✔
707
  } else {
708
    j = bcemit_AJ(fs, BC_JMP, fs->freereg, NO_JMP);
630,259✔
709
  }
710
  jmp_append(fs, &j, jpc);
630,302✔
711
  return j;
630,302✔
712
}
713

714
/* Invert branch condition of bytecode instruction. */
715
static void invertcond(FuncState *fs, ExpDesc *e)
203,343✔
716
{
717
  BCIns *ip = &fs->bcbase[e->u.s.info - 1].ins;
203,343✔
718
  setbc_op(ip, bc_op(*ip)^1);
203,343✔
719
}
720

721
/* Emit conditional branch. */
722
static BCPos bcemit_branch(FuncState *fs, ExpDesc *e, int cond)
94,547✔
723
{
724
  BCPos pc;
94,547✔
725
  if (e->k == VRELOCABLE) {
94,547✔
726
    BCIns *ip = bcptr(fs, e);
48,010✔
727
    if (bc_op(*ip) == BC_NOT) {
48,010✔
728
      *ip = BCINS_AD(cond ? BC_ISF : BC_IST, 0, bc_d(*ip));
45,154✔
729
      return bcemit_jmp(fs);
45,154✔
730
    }
731
  }
732
  if (e->k != VNONRELOC) {
49,393✔
733
    bcreg_reserve(fs, 1);
2,858✔
734
    expr_toreg_nobranch(fs, e, fs->freereg-1);
2,858✔
735
  }
736
  bcemit_AD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info);
82,857✔
737
  pc = bcemit_jmp(fs);
49,393✔
738
  expr_free(fs, e);
49,393✔
739
  return pc;
740
}
741

742
/* Emit branch on true condition. */
743
static void bcemit_branch_t(FuncState *fs, ExpDesc *e)
196,649✔
744
{
745
  BCPos pc;
196,649✔
746
  expr_discharge(fs, e);
196,649✔
747
  if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE)
196,649✔
748
    pc = NO_JMP;  /* Never jump. */
749
  else if (e->k == VJMP)
181,783✔
750
    invertcond(fs, e), pc = e->u.s.info;
84,399✔
751
  else if (e->k == VKFALSE || e->k == VKNIL)
97,384✔
752
    expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs);
22,877✔
753
  else
754
    pc = bcemit_branch(fs, e, 0);
74,507✔
755
  jmp_append(fs, &e->f, pc);
196,649✔
756
  jmp_tohere(fs, e->t);
196,649✔
757
  e->t = NO_JMP;
196,649✔
758
}
196,649✔
759

760
/* Emit branch on false condition. */
761
static void bcemit_branch_f(FuncState *fs, ExpDesc *e)
88,901✔
762
{
763
  BCPos pc;
88,901✔
764
  expr_discharge(fs, e);
88,901✔
765
  if (e->k == VKNIL || e->k == VKFALSE)
88,901✔
766
    pc = NO_JMP;  /* Never jump. */
767
  else if (e->k == VJMP)
67,596✔
768
    pc = e->u.s.info;
33,789✔
769
  else if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE)
33,807✔
770
    expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs);
13,767✔
771
  else
772
    pc = bcemit_branch(fs, e, 1);
20,040✔
773
  jmp_append(fs, &e->t, pc);
88,901✔
774
  jmp_tohere(fs, e->f);
88,901✔
775
  e->f = NO_JMP;
88,901✔
776
}
88,901✔
777

778
/* -- Bytecode emitter for operators -------------------------------------- */
779

780
/* Try constant-folding of arithmetic operators. */
781
static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2)
89,833✔
782
{
783
  TValue o;
89,833✔
784
  lua_Number n;
89,833✔
785
  if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0;
89,833✔
786
  n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD);
1,493✔
787
  setnumV(&o, n);
1,493✔
788
  if (tvisnan(&o) || tvismzero(&o)) return 0;  /* Avoid NaN and -0 as consts. */
1,493✔
789
  if (LJ_DUALNUM) {
1,473✔
790
    int32_t k = lj_num2int(n);
791
    if ((lua_Number)k == n) {
792
      setintV(&e1->u.nval, k);
793
      return 1;
794
    }
795
  }
796
  setnumV(&e1->u.nval, n);
1,473✔
797
  return 1;
1,473✔
798
}
799

800
/* Emit arithmetic operator. */
801
static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
89,833✔
802
{
803
  BCReg rb, rc, t;
89,833✔
804
  uint32_t op;
89,833✔
805
  if (foldarith(opr, e1, e2))
89,833✔
806
    return;
807
  if (opr == OPR_POW) {
88,360✔
808
    op = BC_POW;
90✔
809
    rc = expr_toanyreg(fs, e2);
90✔
810
    rb = expr_toanyreg(fs, e1);
90✔
811
  } else {
812
    op = opr-OPR_ADD+BC_ADDVV;
88,270✔
813
    /* Must discharge 2nd operand first since VINDEXED might free regs. */
814
    expr_toval(fs, e2);
88,270✔
815
    if (expr_isnumk(e2) && (rc = const_num(fs, e2)) <= BCMAX_C)
88,270✔
816
      op -= BC_ADDVV-BC_ADDVN;
10,430✔
817
    else
818
      rc = expr_toanyreg(fs, e2);
77,840✔
819
    /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */
820
    lj_assertFS(expr_isnumk(e1) || e1->k == VNONRELOC,
88,270✔
821
                "bad expr type %d", e1->k);
822
    expr_toval(fs, e1);
88,270✔
823
    /* Avoid two consts to satisfy bytecode constraints. */
824
    if (expr_isnumk(e1) && !expr_isnumk(e2) &&
88,270✔
825
        (t = const_num(fs, e1)) <= BCMAX_B) {
1,207✔
826
      rb = rc; rc = t; op -= BC_ADDVV-BC_ADDNV;
1,207✔
827
    } else {
828
      rb = expr_toanyreg(fs, e1);
87,063✔
829
    }
830
  }
831
  /* Using expr_free might cause asserts if the order is wrong. */
832
  if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--;
88,360✔
833
  if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--;
88,360✔
834
  e1->u.s.info = bcemit_ABC(fs, op, 0, rb, rc);
88,360✔
835
  e1->k = VRELOCABLE;
88,360✔
836
}
837

838
/* Emit comparison operator. */
839
static void bcemit_comp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
344,270✔
840
{
841
  ExpDesc *eret = e1;
344,270✔
842
  BCIns ins;
344,270✔
843
  expr_toval(fs, e1);
344,270✔
844
  if (opr == OPR_EQ || opr == OPR_NE) {
344,270✔
845
    BCOp op = opr == OPR_EQ ? BC_ISEQV : BC_ISNEV;
145,656✔
846
    BCReg ra;
145,656✔
847
    if (expr_isk(e1)) { e1 = e2; e2 = eret; }  /* Need constant in 2nd arg. */
145,656✔
848
    ra = expr_toanyreg(fs, e1);  /* First arg must be in a reg. */
145,656✔
849
    expr_toval(fs, e2);
145,656✔
850
    switch (e2->k) {
145,656✔
851
    case VKNIL: case VKFALSE: case VKTRUE:
48,146✔
852
      ins = BCINS_AD(op+(BC_ISEQP-BC_ISEQV), ra, const_pri(e2));
48,146✔
853
      break;
48,146✔
854
    case VKSTR:
3,330✔
855
      ins = BCINS_AD(op+(BC_ISEQS-BC_ISEQV), ra, const_str(fs, e2));
3,330✔
856
      break;
3,330✔
857
    case VKNUM:
4,533✔
858
      ins = BCINS_AD(op+(BC_ISEQN-BC_ISEQV), ra, const_num(fs, e2));
4,533✔
859
      break;
4,533✔
860
    default:
89,647✔
861
      ins = BCINS_AD(op, ra, expr_toanyreg(fs, e2));
89,647✔
862
      break;
89,647✔
863
    }
864
  } else {
865
    uint32_t op = opr-OPR_LT+BC_ISLT;
198,614✔
866
    BCReg ra, rd;
198,614✔
867
    if ((op-BC_ISLT) & 1) {  /* GT -> LT, GE -> LE */
198,614✔
868
      e1 = e2; e2 = eret;  /* Swap operands. */
99,393✔
869
      op = ((op-BC_ISLT)^3)+BC_ISLT;
99,393✔
870
      expr_toval(fs, e1);
99,393✔
871
      ra = expr_toanyreg(fs, e1);
99,393✔
872
      rd = expr_toanyreg(fs, e2);
99,393✔
873
    } else {
874
      rd = expr_toanyreg(fs, e2);
99,221✔
875
      ra = expr_toanyreg(fs, e1);
99,221✔
876
    }
877
    ins = BCINS_AD(op, ra, rd);
198,614✔
878
  }
879
  /* Using expr_free might cause asserts if the order is wrong. */
880
  if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--;
344,270✔
881
  if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--;
344,270✔
882
  bcemit_INS(fs, ins);
344,270✔
883
  eret->u.s.info = bcemit_jmp(fs);
344,270✔
884
  eret->k = VJMP;
344,270✔
885
}
344,270✔
886

887
/* Fixup left side of binary operator. */
888
static void bcemit_binop_left(FuncState *fs, BinOpr op, ExpDesc *e)
616,622✔
889
{
890
  if (op == OPR_AND) {
616,622✔
891
    bcemit_branch_t(fs, e);
88,047✔
892
  } else if (op == OPR_OR) {
528,575✔
893
    bcemit_branch_f(fs, e);
88,901✔
894
  } else if (op == OPR_CONCAT) {
439,674✔
895
    expr_tonextreg(fs, e);
5,305✔
896
  } else if (op == OPR_EQ || op == OPR_NE) {
434,369✔
897
    if (!expr_isk_nojump(e)) expr_toanyreg(fs, e);
145,660✔
898
  } else {
899
    if (!expr_isnumk_nojump(e)) expr_toanyreg(fs, e);
288,709✔
900
  }
901
}
616,622✔
902

903
/* Emit binary operator. */
904
static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2)
616,158✔
905
{
906
  if (op <= OPR_POW) {
616,158✔
907
    bcemit_arith(fs, op, e1, e2);
89,833✔
908
  } else if (op == OPR_AND) {
526,325✔
909
    lj_assertFS(e1->t == NO_JMP, "jump list not closed");
88,047✔
910
    expr_discharge(fs, e2);
88,047✔
911
    jmp_append(fs, &e2->f, e1->f);
88,047✔
912
    *e1 = *e2;
88,047✔
913
  } else if (op == OPR_OR) {
438,278✔
914
    lj_assertFS(e1->f == NO_JMP, "jump list not closed");
88,901✔
915
    expr_discharge(fs, e2);
88,901✔
916
    jmp_append(fs, &e2->t, e1->t);
88,901✔
917
    *e1 = *e2;
88,901✔
918
  } else if (op == OPR_CONCAT) {
349,377✔
919
    expr_toval(fs, e2);
5,107✔
920
    if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) {
5,107✔
921
      lj_assertFS(e1->u.s.info == bc_b(*bcptr(fs, e2))-1,
1,470✔
922
                  "bad CAT stack layout");
923
      expr_free(fs, e1);
1,470✔
924
      setbc_b(bcptr(fs, e2), e1->u.s.info);
1,470✔
925
      e1->u.s.info = e2->u.s.info;
1,470✔
926
    } else {
927
      expr_tonextreg(fs, e2);
3,637✔
928
      expr_free(fs, e2);
3,637✔
929
      expr_free(fs, e1);
3,637✔
930
      e1->u.s.info = bcemit_ABC(fs, BC_CAT, 0, e1->u.s.info, e2->u.s.info);
3,637✔
931
    }
932
    e1->k = VRELOCABLE;
5,107✔
933
  } else {
934
    lj_assertFS(op == OPR_NE || op == OPR_EQ ||
344,270✔
935
               op == OPR_LT || op == OPR_GE || op == OPR_LE || op == OPR_GT,
936
               "bad binop %d", op);
937
    bcemit_comp(fs, op, e1, e2);
344,270✔
938
  }
939
}
616,158✔
940

941
/* Emit unary operator. */
942
#if LUAJIT_USE_UBSAN
943
/* See https://github.com/LuaJIT/LuaJIT/issues/928. */
944
static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
945
  __attribute__((no_sanitize("signed-integer-overflow")));
946
#endif
947
static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
301,427✔
948
{
949
  if (op == BC_NOT) {
301,427✔
950
    /* Swap true and false lists. */
951
    { BCPos temp = e->f; e->f = e->t; e->t = temp; }
296,926✔
952
    jmp_dropval(fs, e->f);
296,926✔
953
    jmp_dropval(fs, e->t);
296,926✔
954
    expr_discharge(fs, e);
296,926✔
955
    if (e->k == VKNIL || e->k == VKFALSE) {
296,926✔
956
      e->k = VKTRUE;
35,858✔
957
      return;
35,858✔
958
    } else if (expr_isk(e) || (LJ_HASFFI && e->k == VKCDATA)) {
261,068✔
959
      e->k = VKFALSE;
3,090✔
960
      return;
3,090✔
961
    } else if (e->k == VJMP) {
257,978✔
962
      invertcond(fs, e);
118,944✔
963
      return;
118,944✔
964
    } else if (e->k == VRELOCABLE) {
139,034✔
965
      bcreg_reserve(fs, 1);
20,357✔
966
      setbc_a(bcptr(fs, e), fs->freereg-1);
20,357✔
967
      e->u.s.info = fs->freereg-1;
20,357✔
968
      e->k = VNONRELOC;
20,357✔
969
    } else {
970
      lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k);
971
    }
972
  } else {
973
    lj_assertFS(op == BC_UNM || op == BC_LEN, "bad unop %d", op);
4,501✔
974
    if (op == BC_UNM && !expr_hasjump(e)) {  /* Constant-fold negations. */
4,501✔
975
#if LJ_HASFFI
976
      if (e->k == VKCDATA) {  /* Fold in-place since cdata is not interned. */
2,809✔
977
        GCcdata *cd = cdataV(&e->u.nval);
19✔
978
        int64_t *p = (int64_t *)cdataptr(cd);
19✔
979
        if (cd->ctypeid == CTID_COMPLEX_DOUBLE)
19✔
980
          p[1] ^= (int64_t)U64x(80000000,00000000);
3✔
981
        else
982
          *p = -*p;
16✔
983
        return;
19✔
984
      } else
985
#endif
986
      if (expr_isnumk(e) && !expr_numiszero(e)) {  /* Avoid folding to -0. */
2,790✔
987
        TValue *o = expr_numtv(e);
2,630✔
988
        if (tvisint(o)) {
2,630✔
989
          int32_t k = intV(o);
990
          if (k == -k)
991
            setnumV(o, -(lua_Number)k);
992
          else
993
            setintV(o, -k);
994
          return;
995
        } else {
996
          o->u64 ^= U64x(80000000,00000000);
2,630✔
997
          return;
2,630✔
998
        }
999
      }
1000
    }
1001
    expr_toanyreg(fs, e);
1,852✔
1002
  }
1003
  expr_free(fs, e);
140,886✔
1004
  e->u.s.info = bcemit_AD(fs, op, 0, e->u.s.info);
140,886✔
1005
  e->k = VRELOCABLE;
140,886✔
1006
}
1007

1008
/* -- Lexer support ------------------------------------------------------- */
1009

1010
/* Check and consume optional token. */
1011
static int lex_opt(LexState *ls, LexToken tok)
3,364,729✔
1012
{
1013
  if (ls->tok == tok) {
3,364,729✔
1014
    lj_lex_next(ls);
926,149✔
1015
    return 1;
70,987✔
1016
  }
1017
  return 0;
1018
}
1019

1020
/* Check and consume token. */
1021
static void lex_check(LexState *ls, LexToken tok)
734,262✔
1022
{
1023
  if (ls->tok != tok)
734,262✔
1024
    err_token(ls, tok);
3,687✔
1025
  lj_lex_next(ls);
730,575✔
1026
}
730,558✔
1027

1028
/* Check for matching token. */
1029
static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line)
829,586✔
1030
{
1031
  if (!lex_opt(ls, what)) {
829,586✔
1032
    if (line == ls->linenumber) {
965✔
1033
      err_token(ls, what);
681✔
1034
    } else {
1035
      const char *swhat = lj_lex_token2str(ls, what);
284✔
1036
      const char *swho = lj_lex_token2str(ls, who);
284✔
1037
      lj_lex_error(ls, ls->tok, LJ_ERR_XMATCH, swhat, swho, line);
284✔
1038
    }
1039
  }
1040
}
828,613✔
1041

1042
/* Check for string token. */
1043
static GCstr *lex_str(LexState *ls)
1,581,907✔
1044
{
1045
  GCstr *s;
1,581,907✔
1046
  if (ls->tok != TK_name && (LJ_52 || ls->tok != TK_goto))
1,581,907✔
1047
    err_token(ls, TK_name);
220✔
1048
  s = strV(&ls->tokval);
1,581,687✔
1049
  lj_lex_next(ls);
1,581,687✔
1050
  return s;
1,581,687✔
1051
}
1052

1053
/* -- Variable handling --------------------------------------------------- */
1054

1055
#define var_get(ls, fs, i)        ((ls)->vstack[(fs)->varmap[(i)]])
1056

1057
/* Define a new local variable. */
1058
static void var_new(LexState *ls, BCReg n, GCstr *name)
132,869✔
1059
{
1060
  FuncState *fs = ls->fs;
132,869✔
1061
  MSize vtop = ls->vtop;
132,869✔
1062
  checklimit(fs, fs->nactvar+n, LJ_MAX_LOCVAR, "local variables");
132,869✔
1063
  if (LJ_UNLIKELY(vtop >= ls->sizevstack)) {
132,868✔
1064
    if (ls->sizevstack >= LJ_MAX_VSTACK)
29,103✔
1065
      lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK);
×
1066
    lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo);
29,103✔
1067
  }
1068
  lj_assertFS((uintptr_t)name < VARNAME__MAX ||
132,868✔
1069
              lj_tab_getstr(fs->kt, name) != NULL,
1070
              "unanchored variable name");
1071
  /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */
1072
  setgcref(ls->vstack[vtop].name, obj2gco(name));
132,868✔
1073
  fs->varmap[fs->nactvar+n] = (uint16_t)vtop;
132,868✔
1074
  ls->vtop = vtop+1;
132,868✔
1075
}
132,868✔
1076

1077
#define var_new_lit(ls, n, v) \
1078
  var_new(ls, (n), lj_parse_keepstr(ls, "" v, sizeof(v)-1))
1079

1080
#define var_new_fixed(ls, n, vn) \
1081
  var_new(ls, (n), (GCstr *)(uintptr_t)(vn))
1082

1083
/* Add local variables. */
1084
static void var_add(LexState *ls, BCReg nvars)
105,914✔
1085
{
1086
  FuncState *fs = ls->fs;
105,914✔
1087
  BCReg nactvar = fs->nactvar;
105,914✔
1088
  while (nvars--) {
238,495✔
1089
    VarInfo *v = &var_get(ls, fs, nactvar);
132,581✔
1090
    v->startpc = fs->pc;
132,581✔
1091
    v->slot = nactvar++;
132,581✔
1092
    v->info = 0;
132,581✔
1093
  }
1094
  fs->nactvar = nactvar;
105,914✔
1095
}
1096

1097
/* Remove local variables. */
1098
static void var_remove(LexState *ls, BCReg tolevel)
265,965✔
1099
{
1100
  FuncState *fs = ls->fs;
265,965✔
1101
  while (fs->nactvar > tolevel)
393,951✔
1102
    var_get(ls, fs, --fs->nactvar).endpc = fs->pc;
127,986✔
1103
}
1104

1105
/* Lookup local variable name. */
1106
static BCReg var_lookup_local(FuncState *fs, GCstr *n)
1,260,390✔
1107
{
1108
  int i;
1,260,390✔
1109
  for (i = fs->nactvar-1; i >= 0; i--) {
4,671,983✔
1110
    if (n == strref(var_get(fs->ls, fs, i).name))
4,176,743✔
1111
      return (BCReg)i;
765,150✔
1112
  }
1113
  return (BCReg)-1;  /* Not found. */
1114
}
1115

1116
/* Lookup or add upvalue index. */
1117
static MSize var_lookup_uv(FuncState *fs, MSize vidx, ExpDesc *e)
1118
{
1119
  MSize i, n = fs->nuv;
1120
  for (i = 0; i < n; i++)
1121
    if (fs->uvmap[i] == vidx)
1122
      return i;  /* Already exists. */
1123
  /* Otherwise create a new one. */
1124
  checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues");
1125
  lj_assertFS(e->k == VLOCAL || e->k == VUPVAL, "bad expr type %d", e->k);
1126
  fs->uvmap[n] = (uint16_t)vidx;
1127
  fs->uvtmp[n] = (uint16_t)(e->k == VLOCAL ? vidx : LJ_MAX_VSTACK+e->u.s.info);
1128
  fs->nuv = n+1;
1129
  return n;
1130
}
1131

1132
/* Forward declaration. */
1133
static void fscope_uvmark(FuncState *fs, BCReg level);
1134

1135
/* Recursively lookup variables in enclosing functions. */
1136
static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first)
1,681,429✔
1137
{
1138
  if (fs) {
1,681,429✔
1139
    BCReg reg = var_lookup_local(fs, name);
1,260,390✔
1140
    if ((int32_t)reg >= 0) {  /* Local in this function? */
1,260,390✔
1141
      expr_init(e, VLOCAL, reg);
765,150✔
1142
      if (!first)
765,150✔
1143
        fscope_uvmark(fs, reg);  /* Scope now has an upvalue. */
788,596✔
1144
      return (MSize)(e->u.s.aux = (uint32_t)fs->varmap[reg]);
765,150✔
1145
    } else {
1146
      MSize vidx = var_lookup_(fs->prev, name, e, 0);  /* Var in outer func? */
495,240✔
1147
      if ((int32_t)vidx >= 0) {  /* Yes, make it an upvalue here. */
495,180✔
1148
        e->u.s.info = (uint8_t)var_lookup_uv(fs, vidx, e);
26,188✔
1149
        e->k = VUPVAL;
26,187✔
1150
        return vidx;
26,187✔
1151
      }
1152
    }
1153
  } else {  /* Not found in any function, must be a global. */
1154
    expr_init(e, VGLOBAL, 0);
421,039✔
1155
    e->u.sval = name;
421,039✔
1156
  }
1157
  return (MSize)-1;  /* Global. */
1158
}
1159

1160
/* Lookup variable name. */
1161
#define var_lookup(ls, e) \
1162
  var_lookup_((ls)->fs, lex_str(ls), (e), 1)
1163

1164
/* -- Goto an label handling ---------------------------------------------- */
1165

1166
/* Add a new goto or label. */
1167
static MSize gola_new(LexState *ls, GCstr *name, uint8_t info, BCPos pc)
99,055✔
1168
{
1169
  FuncState *fs = ls->fs;
99,055✔
1170
  MSize vtop = ls->vtop;
99,055✔
1171
  if (LJ_UNLIKELY(vtop >= ls->sizevstack)) {
99,055✔
1172
    if (ls->sizevstack >= LJ_MAX_VSTACK)
181✔
1173
      lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK);
×
1174
    lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo);
181✔
1175
  }
1176
  lj_assertFS(name == NAME_BREAK || lj_tab_getstr(fs->kt, name) != NULL,
99,055✔
1177
              "unanchored label name");
1178
  /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */
1179
  setgcref(ls->vstack[vtop].name, obj2gco(name));
99,055✔
1180
  ls->vstack[vtop].startpc = pc;
99,055✔
1181
  ls->vstack[vtop].slot = (uint8_t)fs->nactvar;
99,055✔
1182
  ls->vstack[vtop].info = info;
99,055✔
1183
  ls->vtop = vtop+1;
99,055✔
1184
  return vtop;
99,055✔
1185
}
1186

1187
#define gola_isgoto(v)                ((v)->info & VSTACK_GOTO)
1188
#define gola_islabel(v)                ((v)->info & VSTACK_LABEL)
1189
#define gola_isgotolabel(v)        ((v)->info & (VSTACK_GOTO|VSTACK_LABEL))
1190

1191
/* Patch goto to jump to label. */
1192
static void gola_patch(LexState *ls, VarInfo *vg, VarInfo *vl)
4✔
1193
{
1194
  FuncState *fs = ls->fs;
4✔
1195
  BCPos pc = vg->startpc;
4✔
1196
  setgcrefnull(vg->name);  /* Invalidate pending goto. */
4✔
1197
  setbc_a(&fs->bcbase[pc].ins, vl->slot);
4✔
1198
  jmp_patch(fs, pc, vl->startpc);
4✔
1199
}
4✔
1200

1201
/* Patch goto to close upvalues. */
1202
static void gola_close(LexState *ls, VarInfo *vg)
1203
{
1204
  FuncState *fs = ls->fs;
1205
  BCPos pc = vg->startpc;
1206
  BCIns *ip = &fs->bcbase[pc].ins;
1207
  lj_assertFS(gola_isgoto(vg), "expected goto");
1208
  lj_assertFS(bc_op(*ip) == BC_JMP || bc_op(*ip) == BC_UCLO,
1209
              "bad bytecode op %d", bc_op(*ip));
1210
  setbc_a(ip, vg->slot);
1211
  if (bc_op(*ip) == BC_JMP) {
1212
    BCPos next = jmp_next(fs, pc);
1213
    if (next != NO_JMP) jmp_patch(fs, next, pc);  /* Jump to UCLO. */
1214
    setbc_op(ip, BC_UCLO);  /* Turn into UCLO. */
1215
    setbc_j(ip, NO_JMP);
1216
  }
1217
}
1218

1219
/* Resolve pending forward gotos for label. */
1220
static void gola_resolve(LexState *ls, FuncScope *bl, MSize idx)
1221
{
1222
  VarInfo *vg = ls->vstack + bl->vstart;
1223
  VarInfo *vl = ls->vstack + idx;
1224
  for (; vg < vl; vg++)
1225
    if (gcrefeq(vg->name, vl->name) && gola_isgoto(vg)) {
1226
      if (vg->slot < vl->slot) {
1227
        GCstr *name = strref(var_get(ls, ls->fs, vg->slot).name);
1228
        lj_assertLS((uintptr_t)name >= VARNAME__MAX, "expected goto name");
1229
        ls->linenumber = ls->fs->bcbase[vg->startpc].line;
1230
        lj_assertLS(strref(vg->name) != NAME_BREAK, "unexpected break");
1231
        lj_lex_error(ls, 0, LJ_ERR_XGSCOPE,
1232
                     strdata(strref(vg->name)), strdata(name));
1233
      }
1234
      gola_patch(ls, vg, vl);
1235
    }
1236
}
1237

1238
/* Fixup remaining gotos and labels for scope. */
1239
static void gola_fixup(LexState *ls, FuncScope *bl)
66,353✔
1240
{
1241
  VarInfo *v = ls->vstack + bl->vstart;
66,353✔
1242
  VarInfo *ve = ls->vstack + ls->vtop;
66,353✔
1243
  for (; v < ve; v++) {
133,632✔
1244
    GCstr *name = strref(v->name);
67,287✔
1245
    if (name != NULL) {  /* Only consider remaining valid gotos/labels. */
67,287✔
1246
      if (gola_islabel(v)) {
67,241✔
1247
        VarInfo *vg;
21✔
1248
        setgcrefnull(v->name);  /* Invalidate label that goes out of scope. */
21✔
1249
        for (vg = v+1; vg < ve; vg++)  /* Resolve pending backward gotos. */
45✔
1250
          if (strref(vg->name) == name && gola_isgoto(vg)) {
24✔
1251
            if ((bl->flags&FSCOPE_UPVAL) && vg->slot > v->slot)
4✔
1252
              gola_close(ls, vg);
1✔
1253
            gola_patch(ls, vg, v);
28✔
1254
          }
1255
      } else if (gola_isgoto(v)) {
67,220✔
1256
        if (bl->prev) {  /* Propagate goto or break to outer scope. */
66,365✔
1257
          bl->prev->flags |= name == NAME_BREAK ? FSCOPE_BREAK : FSCOPE_GOLA;
66,357✔
1258
          v->slot = bl->nactvar;
66,357✔
1259
          if ((bl->flags & FSCOPE_UPVAL))
66,357✔
1260
            gola_close(ls, v);
14✔
1261
        } else {  /* No outer scope: undefined goto label or no loop. */
1262
          ls->linenumber = ls->fs->bcbase[v->startpc].line;
8✔
1263
          if (name == NAME_BREAK)
8✔
1264
            lj_lex_error(ls, 0, LJ_ERR_XBREAK);
3✔
1265
          else
1266
            lj_lex_error(ls, 0, LJ_ERR_XLUNDEF, strdata(name));
5✔
1267
        }
1268
      }
1269
    }
1270
  }
1271
}
66,345✔
1272

1273
/* Find existing label. */
1274
static VarInfo *gola_findlabel(LexState *ls, GCstr *name)
59✔
1275
{
1276
  VarInfo *v = ls->vstack + ls->fs->bl->vstart;
59✔
1277
  VarInfo *ve = ls->vstack + ls->vtop;
59✔
1278
  for (; v < ve; v++)
138✔
1279
    if (strref(v->name) == name && gola_islabel(v))
85✔
1280
      return v;
1281
  return NULL;
1282
}
1283

1284
/* -- Scope handling ------------------------------------------------------ */
1285

1286
/* Begin a scope. */
1287
static void fscope_begin(FuncState *fs, FuncScope *bl, int flags)
266,827✔
1288
{
1289
  bl->nactvar = (uint8_t)fs->nactvar;
266,827✔
1290
  bl->flags = flags;
266,827✔
1291
  bl->vstart = fs->ls->vtop;
266,827✔
1292
  bl->prev = fs->bl;
266,827✔
1293
  fs->bl = bl;
266,827✔
1294
  lj_assertFS(fs->freereg == fs->nactvar, "bad regalloc");
266,827✔
1295
}
1296

1297
/* End a scope. */
1298
static void fscope_end(FuncState *fs)
265,965✔
1299
{
1300
  FuncScope *bl = fs->bl;
265,965✔
1301
  LexState *ls = fs->ls;
265,965✔
1302
  fs->bl = bl->prev;
265,965✔
1303
  var_remove(ls, bl->nactvar);
265,965✔
1304
  fs->freereg = fs->nactvar;
265,965✔
1305
  lj_assertFS(bl->nactvar == fs->nactvar, "bad regalloc");
265,965✔
1306
  if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL)
265,965✔
1307
    bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0);
126✔
1308
  if ((bl->flags & FSCOPE_BREAK)) {
265,965✔
1309
    if ((bl->flags & FSCOPE_LOOP)) {
115,811✔
1310
      MSize idx = gola_new(ls, NAME_BREAK, VSTACK_LABEL, fs->pc);
49,485✔
1311
      ls->vtop = idx;  /* Drop break label immediately. */
49,485✔
1312
      gola_resolve(ls, bl, idx);
49,485✔
1313
    } else {  /* Need the fixup step to propagate the breaks. */
1314
      gola_fixup(ls, bl);
66,326✔
1315
      return;
66,326✔
1316
    }
1317
  }
1318
  if ((bl->flags & FSCOPE_GOLA)) {
199,639✔
1319
    gola_fixup(ls, bl);
27✔
1320
  }
1321
}
1322

1323
/* Mark scope as having an upvalue. */
1324
static void fscope_uvmark(FuncState *fs, BCReg level)
23,446✔
1325
{
1326
  FuncScope *bl;
23,446✔
1327
  for (bl = fs->bl; bl && bl->nactvar > level; bl = bl->prev)
23,520✔
1328
    ;
74✔
1329
  if (bl)
23,446✔
1330
    bl->flags |= FSCOPE_UPVAL;
23,446✔
1331
}
1332

1333
/* -- Function state management ------------------------------------------- */
1334

1335
/* Fixup bytecode for prototype. */
1336
static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n)
58,035✔
1337
{
1338
  BCInsLine *base = fs->bcbase;
58,035✔
1339
  MSize i;
58,035✔
1340
  pt->sizebc = n;
58,035✔
1341
  bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF,
116,070✔
1342
                   fs->framesize, 0);
1343
  for (i = 1; i < n; i++)
4,062,830✔
1344
    bc[i] = base[i].ins;
4,004,795✔
1345
}
1346

1347
/* Fixup upvalues for child prototype, step #2. */
1348
static void fs_fixup_uv2(FuncState *fs, GCproto *pt)
1349
{
1350
  VarInfo *vstack = fs->ls->vstack;
1351
  uint16_t *uv = proto_uv(pt);
1352
  MSize i, n = pt->sizeuv;
1353
  for (i = 0; i < n; i++) {
1354
    VarIndex vidx = uv[i];
1355
    if (vidx >= LJ_MAX_VSTACK)
1356
      uv[i] = vidx - LJ_MAX_VSTACK;
1357
    else if ((vstack[vidx].info & VSTACK_VAR_RW))
1358
      uv[i] = vstack[vidx].slot | PROTO_UV_LOCAL;
1359
    else
1360
      uv[i] = vstack[vidx].slot | PROTO_UV_LOCAL | PROTO_UV_IMMUTABLE;
1361
  }
1362
}
1363

1364
/* Fixup constants for prototype. */
1365
static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr)
58,035✔
1366
{
1367
  GCtab *kt;
58,035✔
1368
  TValue *array;
58,035✔
1369
  Node *node;
58,035✔
1370
  MSize i, hmask;
58,035✔
1371
  checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants");
58,035✔
1372
  checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants");
58,034✔
1373
  setmref(pt->k, kptr);
58,033✔
1374
  pt->sizekn = fs->nkn;
58,033✔
1375
  pt->sizekgc = fs->nkgc;
58,033✔
1376
  kt = fs->kt;
58,033✔
1377
  array = tvref(kt->array);
58,033✔
1378
  for (i = 0; i < kt->asize; i++)
64,535✔
1379
    if (tvhaskslot(&array[i])) {
6,502✔
1380
      TValue *tv = &((TValue *)kptr)[tvkslot(&array[i])];
2,563✔
1381
      if (LJ_DUALNUM)
2,563✔
1382
        setintV(tv, (int32_t)i);
1383
      else
1384
        setnumV(tv, (lua_Number)i);
2,563✔
1385
    }
1386
  node = noderef(kt->node);
58,033✔
1387
  hmask = kt->hmask;
58,033✔
1388
  for (i = 0; i <= hmask; i++) {
1,520,495✔
1389
    Node *n = &node[i];
1,462,462✔
1390
    if (tvhaskslot(&n->val)) {
1,462,462✔
1391
      ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val);
409,858✔
1392
      lj_assertFS(!tvisint(&n->key), "unexpected integer key");
409,858✔
1393
      if (tvisnum(&n->key)) {
409,858✔
1394
        TValue *tv = &((TValue *)kptr)[kidx];
73,249✔
1395
        if (LJ_DUALNUM) {
73,249✔
1396
          lua_Number nn = numV(&n->key);
1397
          int32_t k = lj_num2int(nn);
1398
          lj_assertFS(!tvismzero(&n->key), "unexpected -0 key");
1399
          if ((lua_Number)k == nn)
1400
            setintV(tv, k);
1401
          else
1402
            *tv = n->key;
1403
        } else {
1404
          *tv = n->key;
73,249✔
1405
        }
1406
      } else {
1407
        GCobj *o = gcV(&n->key);
336,609✔
1408
        setgcref(((GCRef *)kptr)[~kidx], o);
336,609✔
1409
        lj_gc_objbarrier(fs->L, pt, o);
336,609✔
1410
        if (tvisproto(&n->key))
336,609✔
1411
          fs_fixup_uv2(fs, gco2pt(o));
17,546✔
1412
      }
1413
    }
1414
  }
1415
}
58,033✔
1416

1417
/* Fixup upvalues for prototype, step #1. */
1418
static void fs_fixup_uv1(FuncState *fs, GCproto *pt, uint16_t *uv)
58,033✔
1419
{
1420
  setmref(pt->uv, uv);
58,033✔
1421
  pt->sizeuv = fs->nuv;
58,033✔
1422
  memcpy(uv, fs->uvtmp, fs->nuv*sizeof(VarIndex));
58,033✔
1423
}
1424

1425
#ifndef LUAJIT_DISABLE_DEBUGINFO
1426
/* Prepare lineinfo for prototype. */
1427
static size_t fs_prep_line(FuncState *fs, BCLine numline)
58,035✔
1428
{
1429
  return (fs->pc-1) << (numline < 256 ? 0 : numline < 65536 ? 1 : 2);
259✔
1430
}
1431

1432
/* Fixup lineinfo for prototype. */
1433
static void fs_fixup_line(FuncState *fs, GCproto *pt,
58,033✔
1434
                          void *lineinfo, BCLine numline)
1435
{
1436
  BCInsLine *base = fs->bcbase + 1;
58,033✔
1437
  BCLine first = fs->linedefined;
58,033✔
1438
  MSize i = 0, n = fs->pc-1;
58,033✔
1439
  pt->firstline = fs->linedefined;
58,033✔
1440
  pt->numline = numline;
58,033✔
1441
  setmref(pt->lineinfo, lineinfo);
58,033✔
1442
  if (LJ_LIKELY(numline < 256)) {
58,033✔
1443
    uint8_t *li = (uint8_t *)lineinfo;
3,694,213✔
1444
    do {
3,694,213✔
1445
      BCLine delta = base[i].line - first;
3,694,213✔
1446
      lj_assertFS(delta >= 0 && delta < 256, "bad line delta");
3,694,213✔
1447
      li[i] = (uint8_t)delta;
3,694,213✔
1448
    } while (++i < n);
3,694,213✔
1449
  } else if (LJ_LIKELY(numline < 65536)) {
257✔
1450
    uint16_t *li = (uint16_t *)lineinfo;
48,289✔
1451
    do {
48,289✔
1452
      BCLine delta = base[i].line - first;
48,289✔
1453
      lj_assertFS(delta >= 0 && delta < 65536, "bad line delta");
48,289✔
1454
      li[i] = (uint16_t)delta;
48,289✔
1455
    } while (++i < n);
48,289✔
1456
  } else {
1457
    uint32_t *li = (uint32_t *)lineinfo;
131,215✔
1458
    do {
131,215✔
1459
      BCLine delta = base[i].line - first;
131,215✔
1460
      lj_assertFS(delta >= 0, "bad line delta");
131,215✔
1461
      li[i] = (uint32_t)delta;
131,215✔
1462
    } while (++i < n);
131,215✔
1463
  }
1464
}
58,033✔
1465

1466
/* Prepare variable info for prototype. */
1467
static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
58,035✔
1468
{
1469
  VarInfo *vs =ls->vstack, *ve;
58,035✔
1470
  MSize i, n;
58,035✔
1471
  BCPos lastpc;
58,035✔
1472
  lj_buf_reset(&ls->sb);  /* Copy to temp. string buffer. */
58,035✔
1473
  /* Store upvalue names. */
1474
  for (i = 0, n = fs->nuv; i < n; i++) {
73,647✔
1475
    GCstr *s = strref(vs[fs->uvmap[i]].name);
15,612✔
1476
    MSize len = s->len+1;
15,612✔
1477
    char *p = lj_buf_more(&ls->sb, len);
15,612✔
1478
    p = lj_buf_wmem(p, strdata(s), len);
15,612✔
1479
    setsbufP(&ls->sb, p);
15,612✔
1480
  }
1481
  *ofsvar = sbuflen(&ls->sb);
58,035✔
1482
  lastpc = 0;
58,035✔
1483
  /* Store local variable names and compressed ranges. */
1484
  for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) {
235,557✔
1485
    if (!gola_isgotolabel(vs)) {
177,522✔
1486
      GCstr *s = strref(vs->name);
127,982✔
1487
      BCPos startpc;
127,982✔
1488
      char *p;
127,982✔
1489
      if ((uintptr_t)s < VARNAME__MAX) {
127,982✔
1490
        p = lj_buf_more(&ls->sb, 1 + 2*5);
14,811✔
1491
        *p++ = (char)(uintptr_t)s;
14,811✔
1492
      } else {
1493
        MSize len = s->len+1;
113,171✔
1494
        p = lj_buf_more(&ls->sb, len + 2*5);
113,171✔
1495
        p = lj_buf_wmem(p, strdata(s), len);
113,171✔
1496
      }
1497
      startpc = vs->startpc;
127,982✔
1498
      p = lj_strfmt_wuleb128(p, startpc-lastpc);
127,982✔
1499
      p = lj_strfmt_wuleb128(p, vs->endpc-startpc);
127,982✔
1500
      setsbufP(&ls->sb, p);
127,982✔
1501
      lastpc = startpc;
127,982✔
1502
    }
1503
  }
1504
  lj_buf_putb(&ls->sb, '\0');  /* Terminator for varinfo. */
58,035✔
1505
  return sbuflen(&ls->sb);
58,035✔
1506
}
1507

1508
/* Fixup variable info for prototype. */
1509
static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar)
58,033✔
1510
{
1511
  setmref(pt->uvinfo, p);
58,033✔
1512
  setmref(pt->varinfo, (char *)p + ofsvar);
58,033✔
1513
  memcpy(p, sbufB(&ls->sb), sbuflen(&ls->sb));  /* Copy from temp. buffer. */
58,033✔
1514
}
1515
#else
1516

1517
/* Initialize with empty debug info, if disabled. */
1518
#define fs_prep_line(fs, numline)                (UNUSED(numline), 0)
1519
#define fs_fixup_line(fs, pt, li, numline) \
1520
  pt->firstline = pt->numline = 0, setmref((pt)->lineinfo, NULL)
1521
#define fs_prep_var(ls, fs, ofsvar)                (UNUSED(ofsvar), 0)
1522
#define fs_fixup_var(ls, pt, p, ofsvar) \
1523
  setmref((pt)->uvinfo, NULL), setmref((pt)->varinfo, NULL)
1524

1525
#endif
1526

1527
/* Check if bytecode op returns. */
1528
static int bcopisret(BCOp op)
40,397✔
1529
{
1530
  switch (op) {
40,397✔
1531
  case BC_CALLMT: case BC_CALLT:
1532
  case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
1533
    return 1;
1534
  default:
1535
    return 0;
1536
  }
1537
}
1538

1539
/* Fixup return instruction for prototype. */
1540
static void fs_fixup_ret(FuncState *fs)
58,043✔
1541
{
1542
  BCPos lastpc = fs->pc;
58,043✔
1543
  if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) {
58,043✔
1544
    if ((fs->bl->flags & FSCOPE_UPVAL))
29,107✔
1545
      bcemit_AJ(fs, BC_UCLO, 0, 0);
480✔
1546
    bcemit_AD(fs, BC_RET0, 0, 1);  /* Need final return. */
29,107✔
1547
  }
1548
  fs->bl->flags |= FSCOPE_NOCLOSE;  /* Handled above. */
58,043✔
1549
  fscope_end(fs);
58,043✔
1550
  lj_assertFS(fs->bl == NULL, "bad scope nesting");
58,035✔
1551
  /* May need to fixup returns encoded before first function was created. */
1552
  if (fs->flags & PROTO_FIXUP_RETURN) {
58,035✔
1553
    BCPos pc;
1554
    for (pc = 1; pc < lastpc; pc++) {
2,889✔
1555
      BCIns ins = fs->bcbase[pc].ins;
2,889✔
1556
      BCPos offset;
2,889✔
1557
      switch (bc_op(ins)) {
2,889✔
1558
      case BC_CALLMT: case BC_CALLT:
5✔
1559
      case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
1560
        offset = bcemit_INS(fs, ins);  /* Copy original instruction. */
5✔
1561
        fs->bcbase[offset].line = fs->bcbase[pc].line;
5✔
1562
        offset = offset-(pc+1)+BCBIAS_J;
5✔
1563
        if (offset > BCMAX_D)
5✔
1564
          err_syntax(fs->ls, LJ_ERR_XFIXUP);
×
1565
        /* Replace with UCLO plus branch. */
1566
        fs->bcbase[pc].ins = BCINS_AD(BC_UCLO, 0, offset);
5✔
1567
        break;
5✔
1568
      case BC_FNEW:
1569
        return;  /* We're done. */
1570
      default:
1571
        break;
1572
      }
1573
    }
1574
  }
1575
}
1576

1577
/* Finish a FuncState and return the new prototype. */
1578
static GCproto *fs_finish(LexState *ls, BCLine line)
58,043✔
1579
{
1580
  lua_State *L = ls->L;
58,043✔
1581
  FuncState *fs = ls->fs;
58,043✔
1582
  BCLine numline = line - fs->linedefined;
58,043✔
1583
  size_t sizept, ofsk, ofsuv, ofsli, ofsdbg, ofsvar;
58,043✔
1584
  GCproto *pt;
58,043✔
1585

1586
  /* Apply final fixups. */
1587
  fs_fixup_ret(fs);
58,043✔
1588

1589
  /* Calculate total size of prototype including all colocated arrays. */
1590
  sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef);
58,035✔
1591
  sizept = (sizept + sizeof(TValue)-1) & ~(sizeof(TValue)-1);
58,035✔
1592
  ofsk = sizept; sizept += fs->nkn*sizeof(TValue);
58,035✔
1593
  ofsuv = sizept; sizept += ((fs->nuv+1)&~1)*2;
58,035✔
1594
  ofsli = sizept; sizept += fs_prep_line(fs, numline);
58,035✔
1595
  ofsdbg = sizept; sizept += fs_prep_var(ls, fs, &ofsvar);
58,035✔
1596

1597
  /* Allocate prototype and initialize its fields. */
1598
  pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept);
58,035✔
1599
  pt->gct = ~LJ_TPROTO;
58,035✔
1600
  pt->sizept = (MSize)sizept;
58,035✔
1601
  pt->trace = 0;
58,035✔
1602
  pt->flags = (uint8_t)(fs->flags & ~(PROTO_HAS_RETURN|PROTO_FIXUP_RETURN));
58,035✔
1603
  pt->numparams = fs->numparams;
58,035✔
1604
  pt->framesize = fs->framesize;
58,035✔
1605
  setgcref(pt->chunkname, obj2gco(ls->chunkname));
58,035✔
1606

1607
  /* Close potentially uninitialized gap between bc and kgc. */
1608
  *(uint32_t *)((char *)pt + ofsk - sizeof(GCRef)*(fs->nkgc+1)) = 0;
58,035✔
1609
  fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), fs->pc);
58,035✔
1610
  fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk));
58,035✔
1611
  fs_fixup_uv1(fs, pt, (uint16_t *)((char *)pt + ofsuv));
58,033✔
1612
  fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline);
58,033✔
1613
  fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar);
58,033✔
1614

1615
  lj_vmevent_send(L, BC,
58,033✔
1616
    setprotoV(L, L->top++, pt);
1617
  );
58,033✔
1618

1619
  /* Add a new prototype to the profiler. */
1620
#if LJ_HASMEMPROF
1621
  lj_memprof_add_proto(pt);
58,033✔
1622
#endif
1623
#if LJ_HASSYSPROF
1624
  lj_sysprof_add_proto(pt);
58,033✔
1625
#endif
1626

1627
  L->top--;  /* Pop table of constants. */
58,033✔
1628
  ls->vtop = fs->vbase;  /* Reset variable stack. */
58,033✔
1629
  ls->fs = fs->prev;
58,033✔
1630
  lj_assertL(ls->fs != NULL || ls->tok == TK_eof, "bad parser state");
58,033✔
1631
  return pt;
58,033✔
1632
}
1633

1634
/* Initialize a new FuncState. */
1635
static void fs_init(LexState *ls, FuncState *fs)
74,410✔
1636
{
1637
  lua_State *L = ls->L;
74,410✔
1638
  fs->prev = ls->fs; ls->fs = fs;  /* Append to list. */
74,410✔
1639
  fs->ls = ls;
74,410✔
1640
  fs->vbase = ls->vtop;
74,410✔
1641
  fs->L = L;
74,410✔
1642
  fs->pc = 0;
74,410✔
1643
  fs->lasttarget = 0;
74,410✔
1644
  fs->jpc = NO_JMP;
74,410✔
1645
  fs->freereg = 0;
74,410✔
1646
  fs->nkgc = 0;
74,410✔
1647
  fs->nkn = 0;
74,410✔
1648
  fs->nactvar = 0;
74,410✔
1649
  fs->nuv = 0;
74,410✔
1650
  fs->bl = NULL;
74,410✔
1651
  fs->flags = 0;
74,410✔
1652
  fs->framesize = 1;  /* Minimum frame size. */
74,410✔
1653
  fs->kt = lj_tab_new(L, 0, 0);
74,410✔
1654
  /* Anchor table of constants in stack to avoid being collected. */
1655
  settabV(L, L->top, fs->kt);
74,410✔
1656
  incr_top(L);
74,410✔
1657
}
74,410✔
1658

1659
/* -- Expressions --------------------------------------------------------- */
1660

1661
/* Forward declaration. */
1662
static void expr(LexState *ls, ExpDesc *v);
1663

1664
/* Return string expression. */
1665
static void expr_str(LexState *ls, ExpDesc *e)
277,417✔
1666
{
1667
  expr_init(e, VKSTR, 0);
277,417✔
1668
  e->u.sval = lex_str(ls);
554,834✔
1669
}
1670

1671
/* Return index expression. */
1672
static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e)
1673
{
1674
  /* Already called: expr_toval(fs, e). */
1675
  t->k = VINDEXED;
1676
  if (expr_isnumk(e)) {
1677
#if LJ_DUALNUM
1678
    if (tvisint(expr_numtv(e))) {
1679
      int32_t k = intV(expr_numtv(e));
1680
      if (checku8(k)) {
1681
        t->u.s.aux = BCMAX_C+1+(uint32_t)k;  /* 256..511: const byte key */
1682
        return;
1683
      }
1684
    }
1685
#else
1686
    lua_Number n = expr_numberV(e);
1687
    int32_t k = lj_num2int(n);
1688
    if (checku8(k) && n == (lua_Number)k) {
1689
      t->u.s.aux = BCMAX_C+1+(uint32_t)k;  /* 256..511: const byte key */
1690
      return;
1691
    }
1692
#endif
1693
  } else if (expr_isstrk(e)) {
1694
    BCReg idx = const_str(fs, e);
1695
    if (idx <= BCMAX_C) {
1696
      t->u.s.aux = ~idx;  /* -256..-1: const string key */
1697
      return;
1698
    }
1699
  }
1700
  t->u.s.aux = expr_toanyreg(fs, e);  /* 0..255: register */
1701
}
1702

1703
/* Parse index expression with named field. */
1704
static void expr_field(LexState *ls, ExpDesc *v)
187,244✔
1705
{
1706
  FuncState *fs = ls->fs;
187,244✔
1707
  ExpDesc key;
187,244✔
1708
  expr_toanyreg(fs, v);
187,244✔
1709
  lj_lex_next(ls);  /* Skip dot or colon. */
187,244✔
1710
  expr_str(ls, &key);
187,244✔
1711
  expr_index(fs, v, &key);
187,244✔
1712
}
187,244✔
1713

1714
/* Parse index expression with brackets. */
1715
static void expr_bracket(LexState *ls, ExpDesc *v)
11,558✔
1716
{
1717
  lj_lex_next(ls);  /* Skip '['. */
11,558✔
1718
  expr(ls, v);
23,116✔
1719
  expr_toval(ls->fs, v);
11,558✔
1720
  lex_check(ls, ']');
11,558✔
1721
}
11,558✔
1722

1723
/* Get value of constant expression. */
1724
static void expr_kvalue(FuncState *fs, TValue *v, ExpDesc *e)
389,084✔
1725
{
1726
  UNUSED(fs);
389,084✔
1727
  if (e->k <= VKTRUE) {
389,084✔
1728
    setpriV(v, ~(uint32_t)e->k);
1,037✔
1729
  } else if (e->k == VKSTR) {
388,047✔
1730
    setgcVraw(v, obj2gco(e->u.sval), LJ_TSTR);
272,260✔
1731
  } else {
1732
    lj_assertFS(tvisnumber(expr_numtv(e)), "bad number constant");
243,284✔
1733
    *v = *expr_numtv(e);
243,284✔
1734
  }
1735
}
1736

1737
/* Parse table constructor expression. */
1738
static void expr_table(LexState *ls, ExpDesc *e)
11,248✔
1739
{
1740
  FuncState *fs = ls->fs;
11,248✔
1741
  BCLine line = ls->linenumber;
11,248✔
1742
  GCtab *t = NULL;
11,248✔
1743
  int vcall = 0, needarr = 0, fixt = 0;
11,248✔
1744
  uint32_t narr = 1;  /* First array index. */
11,248✔
1745
  uint32_t nhash = 0;  /* Number of hash entries. */
11,248✔
1746
  BCReg freg = fs->freereg;
11,248✔
1747
  BCPos pc = bcemit_AD(fs, BC_TNEW, freg, 0);
11,248✔
1748
  expr_init(e, VNONRELOC, freg);
11,248✔
1749
  bcreg_reserve(fs, 1);
11,248✔
1750
  freg++;
11,248✔
1751
  lex_check(ls, '{');
11,248✔
1752
  while (ls->tok != '}') {
209,788✔
1753
    ExpDesc key, val;
201,785✔
1754
    vcall = 0;
201,785✔
1755
    if (ls->tok == '[') {
201,785✔
1756
      expr_bracket(ls, &key);  /* Already calls expr_toval. */
756✔
1757
      if (!expr_isk(&key)) expr_index(fs, e, &key);
756✔
1758
      if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++;
756✔
1759
      lex_check(ls, '=');
756✔
1760
    } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) &&
283,325✔
1761
               lj_lex_lookahead(ls) == '=') {
82,296✔
1762
      expr_str(ls, &key);
81,764✔
1763
      lex_check(ls, '=');
81,764✔
1764
      nhash++;
81,764✔
1765
    } else {
1766
      expr_init(&key, VKNUM, 0);
119,265✔
1767
      setintV(&key.u.nval, (int)narr);
119,265✔
1768
      narr++;
119,265✔
1769
      needarr = vcall = 1;
119,265✔
1770
    }
1771
    expr(ls, &val);
403,372✔
1772
    if (expr_isk(&key) && key.k != VKNIL &&
201,587✔
1773
        (key.k == VKSTR || expr_isk_nojump(&val))) {
119,286✔
1774
      TValue k, *v;
198,901✔
1775
      if (!t) {  /* Create template table on demand. */
198,901✔
1776
        BCReg kidx;
4,610✔
1777
        t = lj_tab_new(fs->L, needarr ? narr : 0, hsize2hbits(nhash));
6,549✔
1778
        kidx = const_gc(fs, obj2gco(t), LJ_TTAB);
4,610✔
1779
        fs->bcbase[pc].ins = BCINS_AD(BC_TDUP, freg-1, kidx);
4,610✔
1780
      }
1781
      vcall = 0;
198,901✔
1782
      expr_kvalue(fs, &k, &key);
198,901✔
1783
      v = lj_tab_set(fs->L, t, &k);
198,901✔
1784
      lj_gc_anybarriert(fs->L, t);
198,901✔
1785
      if (expr_isk_nojump(&val)) {  /* Add const key/value to template table. */
198,901✔
1786
        expr_kvalue(fs, v, &val);
190,183✔
1787
      } else {  /* Otherwise create dummy string key (avoids lj_tab_newkey). */
1788
        settabV(fs->L, v, t);  /* Preserve key with table itself as value. */
8,718✔
1789
        fixt = 1;   /* Fix this later, after all resizes. */
8,718✔
1790
        goto nonconst;
8,718✔
1791
      }
1792
    } else {
1793
    nonconst:
2,686✔
1794
      if (val.k != VCALL) { expr_toanyreg(fs, &val); vcall = 0; }
11,404✔
1795
      if (expr_isk(&key)) expr_index(fs, e, &key);
11,404✔
1796
      bcemit_store(fs, e, &val);
11,404✔
1797
    }
1798
    fs->freereg = freg;
201,587✔
1799
    if (!lex_opt(ls, ',') && !lex_opt(ls, ';')) break;
201,587✔
1800
  }
1801
  lex_match(ls, '}', '{', line);
11,050✔
1802
  if (vcall) {
11,048✔
1803
    BCInsLine *ilp = &fs->bcbase[fs->pc-1];
313✔
1804
    ExpDesc en;
313✔
1805
    lj_assertFS(bc_a(ilp->ins) == freg &&
313✔
1806
                bc_op(ilp->ins) == (narr > 256 ? BC_TSETV : BC_TSETB),
1807
                "bad CALL code generation");
1808
    expr_init(&en, VKNUM, 0);
313✔
1809
    en.u.nval.u32.lo = narr-1;
313✔
1810
    en.u.nval.u32.hi = 0x43300000;  /* Biased integer to avoid denormals. */
313✔
1811
    if (narr > 256) { fs->pc--; ilp--; }
313✔
1812
    ilp->ins = BCINS_AD(BC_TSETM, freg, const_num(fs, &en));
313✔
1813
    setbc_b(&ilp[-1].ins, 0);
313✔
1814
  }
1815
  if (pc == fs->pc-1) {  /* Make expr relocable if possible. */
11,048✔
1816
    e->u.s.info = pc;
8,324✔
1817
    fs->freereg--;
8,324✔
1818
    e->k = VRELOCABLE;
8,324✔
1819
  } else {
1820
    e->k = VNONRELOC;  /* May have been changed by expr_index. */
2,724✔
1821
  }
1822
  if (!t) {  /* Construct TNEW RD: hhhhhaaaaaaaaaaa. */
11,048✔
1823
    BCIns *ip = &fs->bcbase[pc].ins;
6,440✔
1824
    if (!needarr) narr = 0;
6,440✔
1825
    else if (narr < 3) narr = 3;
419✔
1826
    else if (narr > 0x7ff) narr = 0x7ff;
1827
    setbc_d(ip, narr|(hsize2hbits(nhash)<<11));
6,440✔
1828
  } else {
1829
    if (needarr && t->asize < narr)
4,608✔
1830
      lj_tab_reasize(fs->L, t, narr-1);
41✔
1831
    if (fixt) {  /* Fix value for dummy keys in template table. */
4,608✔
1832
      Node *node = noderef(t->node);
2,089✔
1833
      uint32_t i, hmask = t->hmask;
2,089✔
1834
      for (i = 0; i <= hmask; i++) {
14,147✔
1835
        Node *n = &node[i];
12,058✔
1836
        if (tvistab(&n->val)) {
12,058✔
1837
          lj_assertFS(tabV(&n->val) == t, "bad dummy key in template table");
8,718✔
1838
          setnilV(&n->val);  /* Turn value into nil. */
8,718✔
1839
        }
1840
      }
1841
    }
1842
    lj_gc_check(fs->L);
4,608✔
1843
  }
1844
}
11,048✔
1845

1846
/* Parse function parameters. */
1847
static BCReg parse_params(LexState *ls, int needself)
21,236✔
1848
{
1849
  FuncState *fs = ls->fs;
21,236✔
1850
  BCReg nparams = 0;
21,236✔
1851
  lex_check(ls, '(');
21,236✔
1852
  if (needself)
21,139✔
1853
    var_new_lit(ls, nparams++, "self");
31✔
1854
  if (ls->tok != ')') {
21,139✔
1855
    do {
34,637✔
1856
      if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) {
34,637✔
1857
        var_new(ls, nparams++, lex_str(ls));
33,937✔
1858
      } else if (ls->tok == TK_dots) {
700✔
1859
        lj_lex_next(ls);
644✔
1860
        fs->flags |= PROTO_VARARG;
644✔
1861
        break;
644✔
1862
      } else {
1863
        err_syntax(ls, LJ_ERR_XPARAM);
56✔
1864
      }
1865
    } while (lex_opt(ls, ','));
33,937✔
1866
  }
1867
  var_add(ls, nparams);
21,083✔
1868
  lj_assertFS(fs->nactvar == nparams, "bad regalloc");
21,083✔
1869
  bcreg_reserve(fs, nparams);
21,083✔
1870
  lex_check(ls, ')');
21,083✔
1871
  return nparams;
21,028✔
1872
}
1873

1874
/* Forward declaration. */
1875
static void parse_chunk(LexState *ls);
1876

1877
/* Parse body of a function. */
1878
static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
21,236✔
1879
{
1880
  FuncState fs, *pfs = ls->fs;
21,236✔
1881
  FuncScope bl;
21,236✔
1882
  GCproto *pt;
21,236✔
1883
  ptrdiff_t oldbase = pfs->bcbase - ls->bcstack;
21,236✔
1884
  fs_init(ls, &fs);
21,236✔
1885
  fscope_begin(&fs, &bl, 0);
21,236✔
1886
  fs.linedefined = line;
21,236✔
1887
  fs.numparams = (uint8_t)parse_params(ls, needself);
21,236✔
1888
  fs.bcbase = pfs->bcbase + pfs->pc;
21,028✔
1889
  fs.bclim = pfs->bclim - pfs->pc;
21,028✔
1890
  bcemit_AD(&fs, BC_FUNCF, 0, 0);  /* Placeholder. */
21,028✔
1891
  parse_chunk(ls);
21,028✔
1892
  if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line);
18,067✔
1893
  pt = fs_finish(ls, (ls->lastline = ls->linenumber));
17,571✔
1894
  pfs->bcbase = ls->bcstack + oldbase;  /* May have been reallocated. */
17,570✔
1895
  pfs->bclim = (BCPos)(ls->sizebcstack - oldbase);
17,570✔
1896
  /* Store new prototype in the constant array of the parent. */
1897
  expr_init(e, VRELOCABLE,
52,710✔
1898
            bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO)));
17,570✔
1899
#if LJ_HASFFI
1900
  pfs->flags |= (fs.flags & PROTO_FFI);
17,570✔
1901
#endif
1902
  if (!(pfs->flags & PROTO_CHILD)) {
17,570✔
1903
    if (pfs->flags & PROTO_HAS_RETURN)
8,320✔
1904
      pfs->flags |= PROTO_FIXUP_RETURN;
1,728✔
1905
    pfs->flags |= PROTO_CHILD;
8,320✔
1906
  }
1907
  lj_lex_next(ls);
17,570✔
1908
}
17,570✔
1909

1910
/* Parse expression list. Last expression is left open. */
1911
static BCReg expr_list(LexState *ls, ExpDesc *v)
772,086✔
1912
{
1913
  BCReg n = 1;
772,086✔
1914
  expr(ls, v);
1,573,773✔
1915
  while (lex_opt(ls, ',')) {
801,687✔
1916
    expr_tonextreg(ls->fs, v);
37,709✔
1917
    expr(ls, v);
75,412✔
1918
    n++;
37,703✔
1919
  }
1920
  return n;
763,978✔
1921
}
1922

1923
/* Parse function argument list. */
1924
static void parse_args(LexState *ls, ExpDesc *e)
308,261✔
1925
{
1926
  FuncState *fs = ls->fs;
308,261✔
1927
  ExpDesc args;
308,261✔
1928
  BCIns ins;
308,261✔
1929
  BCReg base;
308,261✔
1930
  BCLine line = ls->linenumber;
308,261✔
1931
  if (ls->tok == '(') {
308,261✔
1932
#if !LJ_52
1933
    if (line != ls->lastline)
306,860✔
1934
      err_syntax(ls, LJ_ERR_XAMBIG);
1✔
1935
#endif
1936
    lj_lex_next(ls);
306,859✔
1937
    if (ls->tok == ')') {  /* f(). */
306,859✔
1938
      args.k = VVOID;
101,238✔
1939
    } else {
1940
      expr_list(ls, &args);
205,621✔
1941
      if (args.k == VCALL)  /* f(a, b, g()) or f(a, b, ...). */
203,200✔
1942
        setbc_b(bcptr(fs, &args), 0);  /* Pass on multiple results. */
4,605✔
1943
    }
1944
    lex_match(ls, ')', '(', line);
304,438✔
1945
  } else if (ls->tok == '{') {
1,401✔
1946
    expr_table(ls, &args);
138✔
1947
  } else if (ls->tok == TK_string) {
1,263✔
1948
    expr_init(&args, VKSTR, 0);
1,262✔
1949
    args.u.sval = strV(&ls->tokval);
1,262✔
1950
    lj_lex_next(ls);
1,262✔
1951
  } else {
1952
    err_syntax(ls, LJ_ERR_XFUNARG);
1✔
1953
    return;  /* Silence compiler. */
1954
  }
1955
  lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k);
305,542✔
1956
  base = e->u.s.info;  /* Base register for call. */
305,542✔
1957
  if (args.k == VCALL) {
305,542✔
1958
    ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - LJ_FR2);
4,605✔
1959
  } else {
1960
    if (args.k != VVOID)
300,937✔
1961
      expr_tonextreg(fs, &args);
199,699✔
1962
    ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - LJ_FR2);
300,937✔
1963
  }
1964
  expr_init(e, VCALL, bcemit_INS(fs, ins));
305,542✔
1965
  e->u.s.aux = base;
305,542✔
1966
  fs->bcbase[fs->pc - 1].line = line;
305,542✔
1967
  fs->freereg = base+1;  /* Leave one result by default. */
305,542✔
1968
}
1969

1970
/* Parse primary expression. */
1971
static void expr_primary(LexState *ls, ExpDesc *v)
1,585,723✔
1972
{
1973
  FuncState *fs = ls->fs;
1,585,723✔
1974
  /* Parse prefix expression. */
1975
  if (ls->tok == '(') {
1,585,723✔
1976
    BCLine line = ls->linenumber;
401,261✔
1977
    lj_lex_next(ls);
401,261✔
1978
    expr(ls, v);
802,251✔
1979
    lex_match(ls, ')', '(', line);
400,990✔
1980
    expr_discharge(ls->fs, v);
400,844✔
1981
  } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) {
1,184,462✔
1982
    var_lookup(ls, v);
1,177,417✔
1983
  } else {
1984
    err_syntax(ls, LJ_ERR_XSYMBOL);
7,045✔
1985
  }
1986
  for (;;) {  /* Parse multiple expression suffixes. */
2,081,286✔
1987
    if (ls->tok == '.') {
2,081,286✔
1988
      expr_field(ls, v);
186,682✔
1989
    } else if (ls->tok == '[') {
1,894,604✔
1990
      ExpDesc key;
10,802✔
1991
      expr_toanyreg(fs, v);
10,802✔
1992
      expr_bracket(ls, &key);
10,802✔
1993
      expr_index(fs, v, &key);
10,802✔
1994
    } else if (ls->tok == ':') {
1,883,802✔
1995
      ExpDesc key;
8,409✔
1996
      lj_lex_next(ls);
8,409✔
1997
      expr_str(ls, &key);
8,409✔
1998
      bcemit_method(fs, v, &key);
8,409✔
1999
      parse_args(ls, v);
8,409✔
2000
    } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') {
1,875,393✔
2001
      expr_tonextreg(fs, v);
299,852✔
2002
      if (LJ_FR2) bcreg_reserve(fs, 1);
299,852✔
2003
      parse_args(ls, v);
299,852✔
2004
    } else {
2005
      break;
2006
    }
2007
  }
2008
}
1,575,541✔
2009

2010
/* Parse simple expression. */
2011
static void expr_simple(LexState *ls, ExpDesc *v)
2,157,002✔
2012
{
2013
  switch (ls->tok) {
2,157,002✔
2014
  case TK_number:
705,866✔
2015
    expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokval)) ? VKCDATA : VKNUM, 0);
705,866✔
2016
    copyTV(ls->L, &v->u.nval, &ls->tokval);
705,866✔
2017
    break;
2018
  case TK_string:
2019
    expr_init(v, VKSTR, 0);
226,202✔
2020
    v->u.sval = strV(&ls->tokval);
226,202✔
2021
    break;
226,202✔
2022
  case TK_nil:
2023
    expr_init(v, VKNIL, 0);
114,908✔
2024
    break;
2025
  case TK_true:
2026
    expr_init(v, VKTRUE, 0);
16,361✔
2027
    break;
2028
  case TK_false:
2029
    expr_init(v, VKFALSE, 0);
15,080✔
2030
    break;
2031
  case TK_dots: {  /* Vararg. */
822✔
2032
    FuncState *fs = ls->fs;
822✔
2033
    BCReg base;
822✔
2034
    checkcond(ls, fs->flags & PROTO_VARARG, LJ_ERR_XDOTS);
822✔
2035
    bcreg_reserve(fs, 1);
821✔
2036
    base = fs->freereg-1;
821✔
2037
    expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams));
821✔
2038
    v->u.s.aux = base;
821✔
2039
    break;
821✔
2040
  }
2041
  case '{':  /* Table constructor. */
11,110✔
2042
    expr_table(ls, v);
11,110✔
2043
    return;
11,110✔
2044
  case TK_function:
5,877✔
2045
    lj_lex_next(ls);
5,877✔
2046
    parse_body(ls, v, 0, ls->linenumber);
5,877✔
2047
    return;
5,877✔
2048
  default:
1,060,776✔
2049
    expr_primary(ls, v);
1,060,776✔
2050
    return;
1,060,776✔
2051
  }
2052
  lj_lex_next(ls);
1,079,238✔
2053
}
2054

2055
/* Manage syntactic levels to avoid blowing up the stack. */
2056
static void synlevel_begin(LexState *ls)
2,681,809✔
2057
{
2058
  if (++ls->level >= LJ_MAX_XLEVEL)
2,681,809✔
2059
    lj_lex_error(ls, 0, LJ_ERR_XLEVELS);
8✔
2060
}
2061

2062
#define synlevel_end(ls)        ((ls)->level--)
2063

2064
/* Convert token to binary operator. */
2065
static BinOpr token2binop(LexToken tok)
2,449,898✔
2066
{
2067
  switch (tok) {
2,449,898✔
2068
  case '+':        return OPR_ADD;
2069
  case '-':        return OPR_SUB;
4,255✔
2070
  case '*':        return OPR_MUL;
37,669✔
2071
  case '/':        return OPR_DIV;
171✔
2072
  case '%':        return OPR_MOD;
124✔
2073
  case '^':        return OPR_POW;
1,118✔
2074
  case TK_concat: return OPR_CONCAT;
5,305✔
2075
  case TK_ne:        return OPR_NE;
86,047✔
2076
  case TK_eq:        return OPR_EQ;
92,733✔
2077
  case '<':        return OPR_LT;
98,855✔
2078
  case TK_le:        return OPR_LE;
390✔
2079
  case '>':        return OPR_GT;
714✔
2080
  case TK_ge:        return OPR_GE;
98,717✔
2081
  case TK_and:        return OPR_AND;
104,621✔
2082
  case TK_or:        return OPR_OR;
105,305✔
2083
  default:        return OPR_NOBINOPR;
1,766,662✔
2084
  }
2085
}
2086

2087
/* Priorities for each binary operator. ORDER OPR. */
2088
static const struct {
2089
  uint8_t left;                /* Left priority. */
2090
  uint8_t right;        /* Right priority. */
2091
} priority[] = {
2092
  {6,6}, {6,6}, {7,7}, {7,7}, {7,7},        /* ADD SUB MUL DIV MOD */
2093
  {10,9}, {5,4},                        /* POW CONCAT (right associative) */
2094
  {3,3}, {3,3},                                /* EQ NE */
2095
  {3,3}, {3,3}, {3,3}, {3,3},                /* LT GE GT LE */
2096
  {2,2}, {1,1}                                /* AND OR */
2097
};
2098

2099
#define UNARY_PRIORITY                8  /* Priority for unary operators. */
2100

2101
/* Forward declaration. */
2102
static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit);
2103

2104
/* Parse unary expression. */
2105
static void expr_unop(LexState *ls, ExpDesc *v)
2,458,429✔
2106
{
2107
  BCOp op;
2,458,429✔
2108
  if (ls->tok == TK_not) {
2,458,429✔
2109
    op = BC_NOT;
2110
  } else if (ls->tok == '-') {
2,161,503✔
2111
    op = BC_UNM;
2112
  } else if (ls->tok == '#') {
2,158,693✔
2113
    op = BC_LEN;
2114
  } else {
2115
    expr_simple(ls, v);
2,157,002✔
2116
    return;
2,157,002✔
2117
  }
2118
  lj_lex_next(ls);
301,427✔
2119
  expr_binop(ls, v, UNARY_PRIORITY);
301,427✔
2120
  bcemit_unop(ls->fs, op, v);
301,427✔
2121
}
2122

2123
/* Parse binary expressions with priority higher than the limit. */
2124
static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit)
2,458,435✔
2125
{
2126
  BinOpr op;
2,458,435✔
2127
  synlevel_begin(ls);
2,458,435✔
2128
  expr_unop(ls, v);
2,458,429✔
2129
  op = token2binop(ls->tok);
2,449,898✔
2130
  while (op != OPR_NOBINOPR && priority[op].left > limit) {
3,066,056✔
2131
    ExpDesc v2;
616,668✔
2132
    BinOpr nextop;
616,668✔
2133
    lj_lex_next(ls);
616,668✔
2134
    bcemit_binop_left(ls->fs, op, v);
616,622✔
2135
    /* Parse binary expression with higher priority. */
2136
    nextop = expr_binop(ls, &v2, priority[op].right);
616,622✔
2137
    bcemit_binop(ls->fs, op, v, &v2);
616,158✔
2138
    op = nextop;
616,158✔
2139
  }
2140
  synlevel_end(ls);
2,449,388✔
2141
  return op;  /* Return unconsumed binary operator (if any). */
2,449,388✔
2142
}
2143

2144
/* Parse expression. */
2145
static void expr(LexState *ls, ExpDesc *v)
1,540,386✔
2146
{
2147
  expr_binop(ls, v, 0);  /* Priority 0: parse whole expression. */
1,424,399✔
2148
}
763,984✔
2149

2150
/* Assign expression to the next register. */
2151
static void expr_next(LexState *ls)
7,379✔
2152
{
2153
  ExpDesc e;
7,379✔
2154
  expr(ls, &e);
7,379✔
2155
  expr_tonextreg(ls->fs, &e);
7,379✔
2156
}
7,379✔
2157

2158
/* Parse conditional expression. */
2159
static BCPos expr_cond(LexState *ls)
108,608✔
2160
{
2161
  ExpDesc v;
108,608✔
2162
  expr(ls, &v);
108,608✔
2163
  if (v.k == VKNIL) v.k = VKFALSE;
108,602✔
2164
  bcemit_branch_t(ls->fs, &v);
108,602✔
2165
  return v.f;
108,602✔
2166
}
2167

2168
/* -- Assignments --------------------------------------------------------- */
2169

2170
/* List of LHS variables. */
2171
typedef struct LHSVarList {
2172
  ExpDesc v;                        /* LHS variable. */
2173
  struct LHSVarList *prev;        /* Link to previous LHS variable. */
2174
} LHSVarList;
2175

2176
/* Eliminate write-after-read hazards for local variable assignment. */
2177
static void assign_hazard(LexState *ls, LHSVarList *lh, const ExpDesc *v)
2178
{
2179
  FuncState *fs = ls->fs;
2180
  BCReg reg = v->u.s.info;  /* Check against this variable. */
2181
  BCReg tmp = fs->freereg;  /* Rename to this temp. register (if needed). */
2182
  int hazard = 0;
2183
  for (; lh; lh = lh->prev) {
2184
    if (lh->v.k == VINDEXED) {
2185
      if (lh->v.u.s.info == reg) {  /* t[i], t = 1, 2 */
2186
        hazard = 1;
2187
        lh->v.u.s.info = tmp;
2188
      }
2189
      if (lh->v.u.s.aux == reg) {  /* t[i], i = 1, 2 */
2190
        hazard = 1;
2191
        lh->v.u.s.aux = tmp;
2192
      }
2193
    }
2194
  }
2195
  if (hazard) {
2196
    bcemit_AD(fs, BC_MOV, tmp, reg);  /* Rename conflicting variable. */
2197
    bcreg_reserve(fs, 1);
2198
  }
2199
}
2200

2201
/* Adjust LHS/RHS of an assignment. */
2202
static void assign_adjust(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e)
2203
{
2204
  FuncState *fs = ls->fs;
2205
  int32_t extra = (int32_t)nvars - (int32_t)nexps;
2206
  if (e->k == VCALL) {
2207
    extra++;  /* Compensate for the VCALL itself. */
2208
    if (extra < 0) extra = 0;
2209
    setbc_b(bcptr(fs, e), extra+1);  /* Fixup call results. */
2210
    if (extra > 1) bcreg_reserve(fs, (BCReg)extra-1);
2211
  } else {
2212
    if (e->k != VVOID)
2213
      expr_tonextreg(fs, e);  /* Close last expression. */
2214
    if (extra > 0) {  /* Leftover LHS are set to nil. */
2215
      BCReg reg = fs->freereg;
2216
      bcreg_reserve(fs, (BCReg)extra);
2217
      bcemit_nil(fs, reg, (BCReg)extra);
2218
    }
2219
  }
2220
  if (nexps > nvars)
2221
    ls->fs->freereg -= nexps - nvars;  /* Drop leftover regs. */
2222
}
2223

2224
/* Recursively parse assignment statement. */
2225
static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars)
482,072✔
2226
{
2227
  ExpDesc e;
482,072✔
2228
  checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX);
482,072✔
2229
  if (lex_opt(ls, ',')) {  /* Collect LHS list and recurse upwards. */
481,806✔
2230
    LHSVarList vl;
890✔
2231
    vl.prev = lh;
890✔
2232
    expr_primary(ls, &vl.v);
890✔
2233
    if (vl.v.k == VLOCAL)
889✔
2234
      assign_hazard(ls, lh, &vl.v);
526✔
2235
    checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names");
889✔
2236
    parse_assignment(ls, &vl, nvars+1);
889✔
2237
  } else {  /* Parse RHS. */
2238
    BCReg nexps;
480,916✔
2239
    lex_check(ls, '=');
480,916✔
2240
    nexps = expr_list(ls, &e);
477,371✔
2241
    if (nexps == nvars) {
475,926✔
2242
      if (e.k == VCALL) {
475,689✔
2243
        if (bc_op(*bcptr(ls->fs, &e)) == BC_VARG) {  /* Vararg assignment. */
6,412✔
2244
          ls->fs->freereg--;
14✔
2245
          e.k = VRELOCABLE;
14✔
2246
        } else {  /* Multiple call results. */
2247
          e.u.s.info = e.u.s.aux;  /* Base of call is not relocatable. */
6,398✔
2248
          e.k = VNONRELOC;
6,398✔
2249
        }
2250
      }
2251
      bcemit_store(ls->fs, &lh->v, &e);
475,689✔
2252
      return;
475,689✔
2253
    }
2254
    assign_adjust(ls, nvars, nexps, &e);
237✔
2255
  }
2256
  /* Assign RHS to LHS and recurse downwards. */
2257
  expr_init(&e, VNONRELOC, ls->fs->freereg-1);
1,001✔
2258
  bcemit_store(ls->fs, &lh->v, &e);
1,001✔
2259
}
2260

2261
/* Parse call statement or assignment. */
2262
static void parse_call_assign(LexState *ls)
524,057✔
2263
{
2264
  FuncState *fs = ls->fs;
524,057✔
2265
  LHSVarList vl;
524,057✔
2266
  expr_primary(ls, &vl.v);
524,057✔
2267
  if (vl.v.k == VCALL) {  /* Function call statement. */
520,072✔
2268
    setbc_b(bcptr(fs, &vl.v), 1);  /* No results. */
38,889✔
2269
  } else {  /* Start of an assignment. */
2270
    vl.prev = NULL;
481,183✔
2271
    parse_assignment(ls, &vl, 1);
481,183✔
2272
  }
2273
}
514,815✔
2274

2275
/* Parse 'local' statement. */
2276
static void parse_local(LexState *ls)
75,043✔
2277
{
2278
  if (lex_opt(ls, TK_function)) {  /* Local function declaration. */
75,043✔
2279
    ExpDesc v, b;
6,587✔
2280
    FuncState *fs = ls->fs;
6,587✔
2281
    var_new(ls, 0, lex_str(ls));
6,587✔
2282
    expr_init(&v, VLOCAL, fs->freereg);
6,587✔
2283
    v.u.s.aux = fs->varmap[fs->freereg];
6,587✔
2284
    bcreg_reserve(fs, 1);
6,587✔
2285
    var_add(ls, 1);
6,587✔
2286
    parse_body(ls, &b, 0, ls->linenumber);
6,587✔
2287
    /* bcemit_store(fs, &v, &b) without setting VSTACK_VAR_RW. */
2288
    expr_free(fs, &b);
6,587✔
2289
    expr_toreg(fs, &b, v.u.s.info);
6,587✔
2290
    /* The upvalue is in scope, but the local is only valid after the store. */
2291
    var_get(ls, fs, fs->nactvar - 1).startpc = fs->pc;
6,587✔
2292
  } else {  /* Local variable declaration. */
2293
    ExpDesc e;
2294
    BCReg nexps, nvars = 0;
2295
    do {  /* Collect LHS. */
71,368✔
2296
      var_new(ls, nvars++, lex_str(ls));
71,368✔
2297
    } while (lex_opt(ls, ','));
71,355✔
2298
    if (lex_opt(ls, '=')) {  /* Optional RHS. */
68,443✔
2299
      nexps = expr_list(ls, &e);
51,046✔
2300
    } else {  /* Or implicitly set to nil. */
2301
      e.k = VVOID;
17,394✔
2302
      nexps = 0;
17,394✔
2303
    }
2304
    assign_adjust(ls, nvars, nexps, &e);
68,367✔
2305
    var_add(ls, nvars);
136,734✔
2306
  }
2307
}
74,954✔
2308

2309
/* Parse 'function' statement. */
2310
static void parse_func(LexState *ls, BCLine line)
8,980✔
2311
{
2312
  FuncState *fs;
8,980✔
2313
  ExpDesc v, b;
8,980✔
2314
  int needself = 0;
8,980✔
2315
  lj_lex_next(ls);  /* Skip 'function'. */
8,980✔
2316
  /* Parse function name. */
2317
  var_lookup(ls, &v);
8,980✔
2318
  while (ls->tok == '.')  /* Multiple dot-separated fields. */
9,303✔
2319
    expr_field(ls, &v);
531✔
2320
  if (ls->tok == ':') {  /* Optional colon to signify method call. */
8,772✔
2321
    needself = 1;
31✔
2322
    expr_field(ls, &v);
31✔
2323
  }
2324
  parse_body(ls, &b, needself, line);
8,772✔
2325
  fs = ls->fs;
7,240✔
2326
  bcemit_store(fs, &v, &b);
7,240✔
2327
  fs->bcbase[fs->pc - 1].line = line;  /* Set line for the store. */
7,240✔
2328
}
7,240✔
2329

2330
/* -- Control transfer statements ----------------------------------------- */
2331

2332
/* Check for end of block. */
2333
static int parse_isend(LexToken tok)
970,143✔
2334
{
2335
  switch (tok) {
970,143✔
2336
  case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof:
2337
    return 1;
2338
  default:
2339
    return 0;
844,888✔
2340
  }
2341
}
2342

2343
/* Parse 'return' statement. */
2344
static void parse_return(LexState *ls)
37,117✔
2345
{
2346
  BCIns ins;
37,117✔
2347
  FuncState *fs = ls->fs;
37,117✔
2348
  lj_lex_next(ls);  /* Skip 'return'. */
37,117✔
2349
  fs->flags |= PROTO_HAS_RETURN;
37,107✔
2350
  if (parse_isend(ls->tok) || ls->tok == ';') {  /* Bare return. */
37,107✔
2351
    ins = BCINS_AD(BC_RET0, 0, 1);
2352
  } else {  /* Return with one or more values. */
2353
    ExpDesc e;  /* Receives the _last_ expression in the list. */
36,753✔
2354
    BCReg nret = expr_list(ls, &e);
36,753✔
2355
    if (nret == 1) {  /* Return one result. */
32,584✔
2356
      if (e.k == VCALL) {  /* Check for tail call. */
32,324✔
2357
        BCIns *ip = bcptr(fs, &e);
5,181✔
2358
        /* It doesn't pay off to add BC_VARGT just for 'return ...'. */
2359
        if (bc_op(*ip) == BC_VARG) goto notailcall;
5,181✔
2360
        fs->pc--;
5,178✔
2361
        ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip));
5,178✔
2362
      } else {  /* Can return the result from any register. */
2363
        ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2);
27,143✔
2364
      }
2365
    } else {
2366
      if (e.k == VCALL) {  /* Append all results from a call. */
260✔
2367
      notailcall:
57✔
2368
        setbc_b(bcptr(fs, &e), 0);
60✔
2369
        ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar);
60✔
2370
      } else {
2371
        expr_tonextreg(fs, &e);  /* Force contiguous registers. */
203✔
2372
        ins = BCINS_AD(BC_RET, fs->nactvar, nret+1);
203✔
2373
      }
2374
    }
2375
  }
2376
  if (fs->flags & PROTO_CHILD)
32,938✔
2377
    bcemit_AJ(fs, BC_UCLO, 0, 0);  /* May need to close upvalues first. */
2,517✔
2378
  bcemit_INS(fs, ins);
32,938✔
2379
}
32,938✔
2380

2381
/* Parse 'break' statement. */
2382
static void parse_break(LexState *ls)
49,514✔
2383
{
2384
  ls->fs->bl->flags |= FSCOPE_BREAK;
49,514✔
2385
  gola_new(ls, NAME_BREAK, VSTACK_GOTO, bcemit_jmp(ls->fs));
49,514✔
2386
}
49,514✔
2387

2388
/* Parse 'goto' statement. */
2389
static void parse_goto(LexState *ls)
25✔
2390
{
2391
  FuncState *fs = ls->fs;
25✔
2392
  GCstr *name = lex_str(ls);
25✔
2393
  VarInfo *vl = gola_findlabel(ls, name);
25✔
2394
  if (vl)  /* Treat backwards goto within same scope like a loop. */
25✔
2395
    bcemit_AJ(fs, BC_LOOP, vl->slot, -1);  /* No BC range check. */
3✔
2396
  fs->bl->flags |= FSCOPE_GOLA;
25✔
2397
  gola_new(ls, name, VSTACK_GOTO, bcemit_jmp(fs));
25✔
2398
}
25✔
2399

2400
/* Parse label. */
2401
static void parse_label(LexState *ls)
34✔
2402
{
2403
  FuncState *fs = ls->fs;
34✔
2404
  GCstr *name;
34✔
2405
  MSize idx;
34✔
2406
  fs->lasttarget = fs->pc;
34✔
2407
  fs->bl->flags |= FSCOPE_GOLA;
34✔
2408
  lj_lex_next(ls);  /* Skip '::'. */
34✔
2409
  name = lex_str(ls);
34✔
2410
  if (gola_findlabel(ls, name))
68✔
2411
    lj_lex_error(ls, 0, LJ_ERR_XLDUP, strdata(name));
3✔
2412
  idx = gola_new(ls, name, VSTACK_LABEL, fs->pc);
31✔
2413
  lex_check(ls, TK_label);
31✔
2414
  /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */
2415
  for (;;) {
35✔
2416
    if (ls->tok == TK_label) {
33✔
2417
      synlevel_begin(ls);
3✔
2418
      parse_label(ls);
3✔
2419
      synlevel_end(ls);
2✔
2420
    } else if (LJ_52 && ls->tok == ';') {
30✔
2421
      lj_lex_next(ls);
2422
    } else {
2423
      break;
2424
    }
2425
  }
2426
  /* Trailing label is considered to be outside of scope. */
2427
  if (parse_isend(ls->tok) && ls->tok != TK_until)
30✔
2428
    ls->vstack[idx].slot = fs->bl->nactvar;
11✔
2429
  gola_resolve(ls, fs->bl, idx);
30✔
2430
}
26✔
2431

2432
/* -- Blocks, loops and conditional statements ---------------------------- */
2433

2434
/* Parse a block. */
2435
static void parse_block(LexState *ls)
132,722✔
2436
{
2437
  FuncState *fs = ls->fs;
132,722✔
2438
  FuncScope bl;
132,722✔
2439
  fscope_begin(fs, &bl, 0);
132,722✔
2440
  parse_chunk(ls);
132,722✔
2441
  fscope_end(fs);
131,980✔
2442
}
131,980✔
2443

2444
/* Parse 'while' statement. */
2445
static void parse_while(LexState *ls, BCLine line)
33,362✔
2446
{
2447
  FuncState *fs = ls->fs;
33,362✔
2448
  BCPos start, loop, condexit;
33,362✔
2449
  FuncScope bl;
33,362✔
2450
  lj_lex_next(ls);  /* Skip 'while'. */
33,362✔
2451
  start = fs->lasttarget = fs->pc;
33,362✔
2452
  condexit = expr_cond(ls);
33,362✔
2453
  fscope_begin(fs, &bl, FSCOPE_LOOP);
33,361✔
2454
  lex_check(ls, TK_do);
33,361✔
2455
  loop = bcemit_AD(fs, BC_LOOP, fs->nactvar, 0);
33,360✔
2456
  parse_block(ls);
33,360✔
2457
  jmp_patch(fs, bcemit_jmp(fs), start);
33,161✔
2458
  lex_match(ls, TK_end, TK_while, line);
33,161✔
2459
  fscope_end(fs);
33,159✔
2460
  jmp_tohere(fs, condexit);
33,159✔
2461
  jmp_patchins(fs, loop, fs->pc);
33,159✔
2462
}
33,159✔
2463

2464
/* Parse 'repeat' statement. */
2465
static void parse_repeat(LexState *ls, BCLine line)
16,456✔
2466
{
2467
  FuncState *fs = ls->fs;
16,456✔
2468
  BCPos loop = fs->lasttarget = fs->pc;
16,456✔
2469
  BCPos condexit;
16,456✔
2470
  FuncScope bl1, bl2;
16,456✔
2471
  fscope_begin(fs, &bl1, FSCOPE_LOOP);  /* Breakable loop scope. */
16,456✔
2472
  fscope_begin(fs, &bl2, 0);  /* Inner scope. */
16,456✔
2473
  lj_lex_next(ls);  /* Skip 'repeat'. */
16,456✔
2474
  bcemit_AD(fs, BC_LOOP, fs->nactvar, 0);
16,456✔
2475
  parse_chunk(ls);
16,456✔
2476
  lex_match(ls, TK_until, TK_repeat, line);
16,455✔
2477
  condexit = expr_cond(ls);  /* Parse condition (still inside inner scope). */
16,454✔
2478
  if (!(bl2.flags & FSCOPE_UPVAL)) {  /* No upvalues? Just end inner scope. */
16,454✔
2479
    fscope_end(fs);
16,450✔
2480
  } else {  /* Otherwise generate: cond: UCLO+JMP out, !cond: UCLO+JMP loop. */
2481
    parse_break(ls);  /* Break from loop and close upvalues. */
4✔
2482
    jmp_tohere(fs, condexit);
4✔
2483
    fscope_end(fs);  /* End inner scope and close upvalues. */
4✔
2484
    condexit = bcemit_jmp(fs);
4✔
2485
  }
2486
  jmp_patch(fs, condexit, loop);  /* Jump backwards if !cond. */
16,454✔
2487
  jmp_patchins(fs, loop, fs->pc);
16,454✔
2488
  fscope_end(fs);  /* End loop scope. */
16,454✔
2489
}
16,454✔
2490

2491
/* Parse numeric 'for'. */
2492
static void parse_for_num(LexState *ls, GCstr *varname, BCLine line)
3,644✔
2493
{
2494
  FuncState *fs = ls->fs;
3,644✔
2495
  BCReg base = fs->freereg;
3,644✔
2496
  FuncScope bl;
3,644✔
2497
  BCPos loop, loopend;
3,644✔
2498
  /* Hidden control variables. */
2499
  var_new_fixed(ls, FORL_IDX, VARNAME_FOR_IDX);
3,644✔
2500
  var_new_fixed(ls, FORL_STOP, VARNAME_FOR_STOP);
3,644✔
2501
  var_new_fixed(ls, FORL_STEP, VARNAME_FOR_STEP);
3,644✔
2502
  /* Visible copy of index variable. */
2503
  var_new(ls, FORL_EXT, varname);
3,644✔
2504
  lex_check(ls, '=');
3,644✔
2505
  expr_next(ls);
3,644✔
2506
  lex_check(ls, ',');
3,644✔
2507
  expr_next(ls);
3,644✔
2508
  if (lex_opt(ls, ',')) {
3,644✔
2509
    expr_next(ls);
91✔
2510
  } else {
2511
    bcemit_AD(fs, BC_KSHORT, fs->freereg, 1);  /* Default step is 1. */
3,553✔
2512
    bcreg_reserve(fs, 1);
3,553✔
2513
  }
2514
  var_add(ls, 3);  /* Hidden control variables. */
3,644✔
2515
  lex_check(ls, TK_do);
3,644✔
2516
  loop = bcemit_AJ(fs, BC_FORI, base, NO_JMP);
3,643✔
2517
  fscope_begin(fs, &bl, 0);  /* Scope for visible variables. */
3,643✔
2518
  var_add(ls, 1);
3,643✔
2519
  bcreg_reserve(fs, 1);
3,643✔
2520
  parse_block(ls);
3,643✔
2521
  fscope_end(fs);
3,643✔
2522
  /* Perform loop inversion. Loop control instructions are at the end. */
2523
  loopend = bcemit_AJ(fs, BC_FORL, base, NO_JMP);
3,643✔
2524
  fs->bcbase[loopend].line = line;  /* Fix line for control ins. */
3,643✔
2525
  jmp_patchins(fs, loopend, loop+1);
3,643✔
2526
  jmp_patchins(fs, loop, fs->pc);
3,643✔
2527
}
3,643✔
2528

2529
/* Try to predict whether the iterator is next() and specialize the bytecode.
2530
** Detecting next() and pairs() by name is simplistic, but quite effective.
2531
** The interpreter backs off if the check for the closure fails at runtime.
2532
*/
2533
static int predict_next(LexState *ls, FuncState *fs, BCPos pc)
2534
{
2535
  BCIns ins;
2536
  GCstr *name;
2537
  cTValue *o;
2538
  if (pc >= fs->bclim) return 0;
2539
  ins = fs->bcbase[pc].ins;
2540
  switch (bc_op(ins)) {
2541
  case BC_MOV:
2542
    if (bc_d(ins) >= fs->nactvar) return 0;
2543
    name = gco2str(gcref(var_get(ls, fs, bc_d(ins)).name));
2544
    break;
2545
  case BC_UGET:
2546
    name = gco2str(gcref(ls->vstack[fs->uvmap[bc_d(ins)]].name));
2547
    break;
2548
  case BC_GGET:
2549
    /* There's no inverse index (yet), so lookup the strings. */
2550
    o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs"));
2551
    if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins))
2552
      return 1;
2553
    o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next"));
2554
    if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins))
2555
      return 1;
2556
    return 0;
2557
  default:
2558
    return 0;
2559
  }
2560
  return (name->len == 5 && !strcmp(strdata(name), "pairs")) ||
2561
         (name->len == 4 && !strcmp(strdata(name), "next"));
2562
}
2563

2564
/* Parse 'for' iterator. */
2565
static void parse_for_iter(LexState *ls, GCstr *indexname)
1,295✔
2566
{
2567
  FuncState *fs = ls->fs;
1,295✔
2568
  ExpDesc e;
1,295✔
2569
  BCReg nvars = 0;
1,295✔
2570
  BCLine line;
1,295✔
2571
  BCReg base = fs->freereg + 3;
1,295✔
2572
  BCPos loop, loopend, exprpc = fs->pc;
1,295✔
2573
  FuncScope bl;
1,295✔
2574
  int isnext;
1,295✔
2575
  /* Hidden control variables. */
2576
  var_new_fixed(ls, nvars++, VARNAME_FOR_GEN);
1,295✔
2577
  var_new_fixed(ls, nvars++, VARNAME_FOR_STATE);
1,295✔
2578
  var_new_fixed(ls, nvars++, VARNAME_FOR_CTL);
1,295✔
2579
  /* Visible variables returned from iterator. */
2580
  var_new(ls, nvars++, indexname);
1,295✔
2581
  while (lex_opt(ls, ','))
2,497✔
2582
    var_new(ls, nvars++, lex_str(ls));
1,202✔
2583
  lex_check(ls, TK_in);
1,295✔
2584
  line = ls->linenumber;
1,295✔
2585
  assign_adjust(ls, 3, expr_list(ls, &e), &e);
1,295✔
2586
  /* The iterator needs another 3 [4] slots (func [pc] | state ctl). */
2587
  bcreg_bump(fs, 3+LJ_FR2);
1,295✔
2588
  isnext = (nvars <= 5 && predict_next(ls, fs, exprpc));
1,295✔
2589
  var_add(ls, 3);  /* Hidden control variables. */
1,295✔
2590
  lex_check(ls, TK_do);
1,295✔
2591
  loop = bcemit_AJ(fs, isnext ? BC_ISNEXT : BC_JMP, base, NO_JMP);
1,635✔
2592
  fscope_begin(fs, &bl, 0);  /* Scope for visible variables. */
1,295✔
2593
  var_add(ls, nvars-3);
1,295✔
2594
  bcreg_reserve(fs, nvars-3);
1,295✔
2595
  parse_block(ls);
1,295✔
2596
  fscope_end(fs);
1,295✔
2597
  /* Perform loop inversion. Loop control instructions are at the end. */
2598
  jmp_patchins(fs, loop, fs->pc);
1,295✔
2599
  bcemit_ABC(fs, isnext ? BC_ITERN : BC_ITERC, base, nvars-3+1, 2+1);
1,295✔
2600
  loopend = bcemit_AJ(fs, BC_ITERL, base, NO_JMP);
1,295✔
2601
  fs->bcbase[loopend-1].line = line;  /* Fix line for control ins. */
1,295✔
2602
  fs->bcbase[loopend].line = line;
1,295✔
2603
  jmp_patchins(fs, loopend, loop+1);
1,295✔
2604
}
1,295✔
2605

2606
/* Parse 'for' statement. */
2607
static void parse_for(LexState *ls, BCLine line)
4,940✔
2608
{
2609
  FuncState *fs = ls->fs;
4,940✔
2610
  GCstr *varname;
4,940✔
2611
  FuncScope bl;
4,940✔
2612
  fscope_begin(fs, &bl, FSCOPE_LOOP);
4,940✔
2613
  lj_lex_next(ls);  /* Skip 'for'. */
4,940✔
2614
  varname = lex_str(ls);  /* Get first variable name. */
4,940✔
2615
  if (ls->tok == '=')
4,940✔
2616
    parse_for_num(ls, varname, line);
3,644✔
2617
  else if (ls->tok == ',' || ls->tok == TK_in)
1,296✔
2618
    parse_for_iter(ls, varname);
1,295✔
2619
  else
2620
    err_syntax(ls, LJ_ERR_XFOR);
1✔
2621
  lex_match(ls, TK_end, TK_for, line);
4,938✔
2622
  fscope_end(fs);  /* Resolve break list. */
4,937✔
2623
}
4,937✔
2624

2625
/* Parse condition and 'then' block. */
2626
static BCPos parse_then(LexState *ls)
58,792✔
2627
{
2628
  BCPos condexit;
58,792✔
2629
  lj_lex_next(ls);  /* Skip 'if' or 'elseif'. */
58,792✔
2630
  condexit = expr_cond(ls);
58,792✔
2631
  lex_check(ls, TK_then);
58,787✔
2632
  parse_block(ls);
58,782✔
2633
  return condexit;
58,780✔
2634
}
2635

2636
/* Parse 'if' statement. */
2637
static void parse_if(LexState *ls, BCLine line)
57,864✔
2638
{
2639
  FuncState *fs = ls->fs;
57,864✔
2640
  BCPos flist;
57,864✔
2641
  BCPos escapelist = NO_JMP;
57,864✔
2642
  flist = parse_then(ls);
57,864✔
2643
  while (ls->tok == TK_elseif) {  /* Parse multiple 'elseif' blocks. */
58,792✔
2644
    jmp_append(fs, &escapelist, bcemit_jmp(fs));
928✔
2645
    jmp_tohere(fs, flist);
928✔
2646
    flist = parse_then(ls);
928✔
2647
  }
2648
  if (ls->tok == TK_else) {  /* Parse optional 'else' block. */
57,852✔
2649
    jmp_append(fs, &escapelist, bcemit_jmp(fs));
34,895✔
2650
    jmp_tohere(fs, flist);
34,895✔
2651
    lj_lex_next(ls);  /* Skip 'else'. */
34,895✔
2652
    parse_block(ls);
34,895✔
2653
  } else {
2654
    jmp_append(fs, &escapelist, flist);
22,957✔
2655
  }
2656
  jmp_tohere(fs, escapelist);
57,654✔
2657
  lex_match(ls, TK_end, TK_if, line);
57,654✔
2658
}
57,636✔
2659

2660
/* -- Parse statements ---------------------------------------------------- */
2661

2662
/* Parse a statement. Returns 1 if it must be the last one in a chunk. */
2663
static int parse_stmt(LexState *ls)
808,132✔
2664
{
2665
  BCLine line = ls->linenumber;
808,132✔
2666
  switch (ls->tok) {
808,132✔
2667
  case TK_if:
57,864✔
2668
    parse_if(ls, line);
57,864✔
2669
    break;
57,864✔
2670
  case TK_while:
33,362✔
2671
    parse_while(ls, line);
33,362✔
2672
    break;
33,362✔
2673
  case TK_do:
747✔
2674
    lj_lex_next(ls);
747✔
2675
    parse_block(ls);
747✔
2676
    lex_match(ls, TK_end, TK_do, line);
404✔
2677
    break;
404✔
2678
  case TK_for:
4,940✔
2679
    parse_for(ls, line);
4,940✔
2680
    break;
4,940✔
2681
  case TK_repeat:
16,456✔
2682
    parse_repeat(ls, line);
16,456✔
2683
    break;
16,456✔
2684
  case TK_function:
8,980✔
2685
    parse_func(ls, line);
8,980✔
2686
    break;
8,980✔
2687
  case TK_local:
75,043✔
2688
    lj_lex_next(ls);
75,043✔
2689
    parse_local(ls);
75,043✔
2690
    break;
75,043✔
2691
  case TK_return:
37,117✔
2692
    parse_return(ls);
37,117✔
2693
    return 1;  /* Must be last. */
37,117✔
2694
  case TK_break:
49,510✔
2695
    lj_lex_next(ls);
49,510✔
2696
    parse_break(ls);
49,510✔
2697
    return !LJ_52;  /* Must be last in Lua 5.1. */
49,510✔
2698
#if LJ_52
2699
  case ';':
2700
    lj_lex_next(ls);
2701
    break;
2702
#endif
2703
  case TK_label:
31✔
2704
    parse_label(ls);
31✔
2705
    break;
31✔
2706
  case TK_goto:
26✔
2707
    if (LJ_52 || lj_lex_lookahead(ls) == TK_name) {
26✔
2708
      lj_lex_next(ls);
25✔
2709
      parse_goto(ls);
25✔
2710
      break;
25✔
2711
    }
2712
    /* fallthrough */
2713
  default:
2714
    parse_call_assign(ls);
524,057✔
2715
    break;
524,057✔
2716
  }
2717
  return 0;
2718
}
2719

2720
/* A chunk is a list of statements optionally separated by semicolons. */
2721
static void parse_chunk(LexState *ls)
223,371✔
2722
{
2723
  int islast = 0;
223,371✔
2724
  synlevel_begin(ls);
223,371✔
2725
  while (!islast && !parse_isend(ls->tok)) {
1,015,454✔
2726
    islast = parse_stmt(ls);
808,132✔
2727
    lex_opt(ls, ';');
792,085✔
2728
    lj_assertLS(ls->fs->framesize >= ls->fs->freereg &&
792,085✔
2729
                ls->fs->freereg >= ls->fs->nactvar,
2730
                "bad regalloc");
2731
    ls->fs->freereg = ls->fs->nactvar;  /* Free registers after each stmt. */
792,085✔
2732
  }
2733
  synlevel_end(ls);
207,322✔
2734
}
207,322✔
2735

2736
/* Entry point of bytecode parser. */
2737
GCproto *lj_parse(LexState *ls)
53,174✔
2738
{
2739
  FuncState fs;
53,174✔
2740
  FuncScope bl;
53,174✔
2741
  GCproto *pt;
53,174✔
2742
  lua_State *L = ls->L;
53,174✔
2743
#ifdef LUAJIT_DISABLE_DEBUGINFO
2744
  ls->chunkname = lj_str_newlit(L, "=");
2745
#else
2746
  ls->chunkname = lj_str_newz(L, ls->chunkarg);
53,174✔
2747
#endif
2748
  setstrV(L, L->top, ls->chunkname);  /* Anchor chunkname string. */
53,174✔
2749
  incr_top(L);
53,174✔
2750
  ls->level = 0;
53,174✔
2751
  fs_init(ls, &fs);
53,174✔
2752
  fs.linedefined = 0;
53,174✔
2753
  fs.numparams = 0;
53,174✔
2754
  fs.bcbase = NULL;
53,174✔
2755
  fs.bclim = 0;
53,174✔
2756
  fs.flags |= PROTO_VARARG;  /* Main chunk is always a vararg func. */
53,174✔
2757
  fscope_begin(&fs, &bl, 0);
53,174✔
2758
  bcemit_AD(&fs, BC_FUNCV, 0, 0);  /* Placeholder. */
53,174✔
2759
  lj_lex_next(ls);  /* Read-ahead first token. */
53,174✔
2760
  parse_chunk(ls);
53,165✔
2761
  if (ls->tok != TK_eof)
40,820✔
2762
    err_token(ls, TK_eof);
348✔
2763
  pt = fs_finish(ls, ls->linenumber);
40,472✔
2764
  L->top--;  /* Drop chunkname. */
40,463✔
2765
  lj_assertL(fs.prev == NULL && ls->fs == NULL, "mismatched frame nesting");
40,463✔
2766
  lj_assertL(pt->sizeuv == 0, "toplevel proto has upvalues");
40,463✔
2767
  return pt;
40,463✔
2768
}
2769

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc