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

tarantool / luajit / 6035198545

31 Aug 2023 08:55AM UTC coverage: 88.225% (+0.4%) from 87.822%
6035198545

push

github

fckxorg
test: don't skip tool CLI flag for tarantool

That skipcond was introduced to overcome the obstacles
of LuaJIT's integration testing in Tarantool. Since
the required patch is now in the Tarantool master, this
skipcond is now unnecessary.

Related to tarantool/tarantool#5688

5340 of 5975 branches covered (0.0%)

Branch coverage included in aggregate %.

20495 of 23308 relevant lines covered (87.93%)

1297339.67 hits per line

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

99.56
/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)
2,479,637✔
90
{
91
  e->k = k;
2,479,637✔
92
  e->u.s.info = info;
2,479,637✔
93
  e->f = e->t = NO_JMP;
2,479,637✔
94
}
142,929✔
95

96
/* Check number constant for +-0. */
97
static int expr_numiszero(ExpDesc *e)
2,387✔
98
{
99
  TValue *o = expr_numtv(e);
2,387✔
100
  return tvisint(o) ? (intV(o) == 0) : tviszero(o);
2,387✔
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)
145,436✔
212
{
213
  lua_State *L = fs->L;
145,436✔
214
  TValue *o;
145,436✔
215
  lj_assertFS(expr_isnumk(e), "bad usage");
145,436✔
216
  o = lj_tab_set(L, fs->kt, &e->u.nval);
145,436✔
217
  if (tvhaskslot(o))
145,436✔
218
    return tvkslot(o);
1,888✔
219
  o->u64 = fs->nkn;
143,548✔
220
  return fs->nkn++;
143,548✔
221
}
222

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

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

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

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

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

269
/* Get next element in jump list. */
270
static BCPos jmp_next(FuncState *fs, BCPos pc)
733,750✔
271
{
272
  ptrdiff_t delta = bc_j(fs->bcbase[pc].ins);
733,750✔
273
  if ((BCPos)delta == NO_JMP)
733,750✔
274
    return NO_JMP;
275
  else
276
    return (BCPos)(((ptrdiff_t)pc+1)+delta);
74,789✔
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)
592,776✔
318
{
319
  for (; list != NO_JMP; list = jmp_next(fs, list))
628,724✔
320
    jmp_patchtestreg(fs, list, NO_REG);
35,948✔
321
}
592,776✔
322

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

334
/* Append to jump list. */
335
static void jmp_append(FuncState *fs, BCPos *l1, BCPos l2)
2,061,468✔
336
{
337
  if (l2 == NO_JMP) {
2,061,468✔
338
    return;
339
  } else if (*l1 == NO_JMP) {
893,307✔
340
    *l1 = l2;
818,516✔
341
  } else {
342
    BCPos list = *l1;
343
    BCPos next;
344
    while ((next = jmp_next(fs, list)) != NO_JMP)  /* Find last element. */
78,332✔
345
      list = next;
346
    jmp_patchins(fs, list, l2);
74,791✔
347
  }
348
}
349

350
/* Patch jump list and preserve produced values. */
351
static void jmp_patchval(FuncState *fs, BCPos list, BCPos vtarget,
4,348,703✔
352
                         BCReg reg, BCPos dtarget)
353
{
354
  while (list != NO_JMP) {
4,348,703✔
355
    BCPos next = jmp_next(fs, list);
619,470✔
356
    if (jmp_patchtestreg(fs, list, reg))
619,470✔
357
      jmp_patchins(fs, list, vtarget);  /* Jump to target with value. */
70,904✔
358
    else
359
      jmp_patchins(fs, list, dtarget);  /* Jump to default target. */
5,516,739✔
360
    list = next;
361
  }
362
}
4,348,703✔
363

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

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

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

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

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

402
/* Free register. */
403
static void bcreg_free(FuncState *fs, BCReg reg)
437,766✔
404
{
405
  if (reg >= fs->nactvar) {
437,766✔
406
    fs->freereg--;
251,136✔
407
    lj_assertFS(reg == fs->freereg, "bad regfree");
3,928✔
408
  }
409
}
410

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

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

420
/* Emit bytecode instruction. */
421
static BCPos bcemit_INS(FuncState *fs, BCIns ins)
3,721,455✔
422
{
423
  BCPos pc = fs->pc;
3,721,455✔
424
  LexState *ls = fs->ls;
3,721,455✔
425
  jmp_patchval(fs, fs->jpc, pc, NO_REG, pc);
3,721,455✔
426
  fs->jpc = NO_JMP;
3,721,455✔
427
  if (LJ_UNLIKELY(pc >= fs->bclim)) {
3,721,455✔
428
    ptrdiff_t base = fs->bcbase - ls->bcstack;
139,530✔
429
    checklimit(fs, ls->sizebcstack, LJ_MAX_BCINS, "bytecode instructions");
139,530✔
430
    lj_mem_growvec(fs->L, ls->bcstack, ls->sizebcstack, LJ_MAX_BCINS,BCInsLine);
139,530✔
431
    fs->bclim = (BCPos)(ls->sizebcstack - base);
139,530✔
432
    fs->bcbase = ls->bcstack + base;
139,530✔
433
  }
434
  fs->bcbase[pc].ins = ins;
3,721,455✔
435
  fs->bcbase[pc].line = ls->lastline;
3,721,455✔
436
  fs->pc = pc+1;
3,721,455✔
437
  return pc;
3,721,455✔
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)
5,393,755✔
450
{
451
  BCIns ins;
5,393,755✔
452
  if (e->k == VUPVAL) {
5,393,755✔
453
    ins = BCINS_AD(BC_UGET, 0, e->u.s.info);
12,957✔
454
  } else if (e->k == VGLOBAL) {
5,380,798✔
455
    ins = BCINS_AD(BC_GGET, 0, const_str(fs, e));
280,868✔
456
  } else if (e->k == VINDEXED) {
5,099,930✔
457
    BCReg rc = e->u.s.aux;
22,830✔
458
    if ((int32_t)rc < 0) {
22,830✔
459
      ins = BCINS_ABC(BC_TGETS, 0, e->u.s.info, ~rc);
17,508✔
460
    } else if (rc > BCMAX_C) {
5,322✔
461
      ins = BCINS_ABC(BC_TGETB, 0, e->u.s.info, rc-(BCMAX_C+1));
1,394✔
462
    } else {
463
      bcreg_free(fs, rc);
3,928✔
464
      ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc);
3,928✔
465
    }
466
    bcreg_free(fs, e->u.s.info);
22,830✔
467
  } else if (e->k == VCALL) {
5,077,100✔
468
    e->u.s.info = e->u.s.aux;
239,458✔
469
    e->k = VNONRELOC;
239,458✔
470
    return;
239,458✔
471
  } else if (e->k == VLOCAL) {
4,837,642✔
472
    e->k = VNONRELOC;
207,401✔
473
    return;
207,401✔
474
  } else {
475
    return;
476
  }
477
  e->u.s.info = bcemit_INS(fs, ins);
316,655✔
478
  e->k = VRELOCABLE;
316,655✔
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,060✔
483
{
484
  if (fs->pc > fs->lasttarget) {  /* No jumps to current position? */
46,060✔
485
    BCIns *ip = &fs->bcbase[fs->pc-1].ins;
30,172✔
486
    BCReg pto, pfrom = bc_a(*ip);
30,172✔
487
    switch (bc_op(*ip)) {  /* Try to merge with the previous instruction. */
30,172✔
488
    case BC_KPRI:
730✔
489
      if (bc_d(*ip) != ~LJ_TNIL) break;
730✔
490
      if (from == pfrom) {
724✔
491
        if (n == 1) return;
×
492
      } else if (from == pfrom+1) {
724✔
493
        from = pfrom;
82✔
494
        n++;
82✔
495
      } else {
496
        break;
497
      }
498
      *ip = BCINS_AD(BC_KNIL, from, from+n-1);  /* Replace KPRI. */
82✔
499
      return;
82✔
500
    case BC_KNIL:
132✔
501
      pto = bc_d(*ip);
132✔
502
      if (pfrom <= from && from <= pto+1) {  /* Can we connect both ranges? */
132✔
503
        if (from+n-1 > pto)
131✔
504
          setbc_d(ip, from+n-1);  /* Patch previous instruction range. */
129✔
505
        return;
131✔
506
      }
507
      break;
508
    default:
509
      break;
510
    }
511
  }
16,536✔
512
  /* Emit new instruction or replace old instruction. */
513
  bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) :
45,942✔
514
                          BCINS_AD(BC_KNIL, from, from+n-1));
95✔
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,482,562✔
519
{
520
  BCIns ins;
1,482,562✔
521
  expr_discharge(fs, e);
1,482,562✔
522
  if (e->k == VKSTR) {
1,482,562✔
523
    ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e));
154,033✔
524
  } else if (e->k == VKNUM) {
1,328,529✔
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);
545,972✔
532
    int32_t k = lj_num2int(n);
545,972✔
533
    if (checki16(k) && n == (lua_Number)k)
545,972✔
534
      ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k);
414,181✔
535
    else
536
#endif
537
      ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e));
131,791✔
538
#if LJ_HASFFI
539
  } else if (e->k == VKCDATA) {
782,557✔
540
    fs->flags |= PROTO_FFI;
139✔
541
    ins = BCINS_AD(BC_KCDATA, reg,
139✔
542
                   const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA));
543
#endif
544
  } else if (e->k == VRELOCABLE) {
782,418✔
545
    setbc_a(bcptr(fs, e), reg);
422,390✔
546
    goto noins;
422,390✔
547
  } else if (e->k == VNONRELOC) {
360,028✔
548
    if (reg == e->u.s.info)
72,244✔
549
      goto noins;
26,873✔
550
    ins = BCINS_AD(BC_MOV, reg, e->u.s.info);
45,371✔
551
  } else if (e->k == VKNIL) {
287,784✔
552
    bcemit_nil(fs, reg, 1);
29,004✔
553
    goto noins;
29,004✔
554
  } else if (e->k <= VKTRUE) {
258,780✔
555
    ins = BCINS_AD(BC_KPRI, reg, const_pri(e));
34,494✔
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);
780,009✔
561
noins:
1,258,276✔
562
  e->u.s.info = reg;
1,258,276✔
563
  e->k = VNONRELOC;
1,258,276✔
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,444,392✔
571
{
572
  expr_toreg_nobranch(fs, e, reg);
1,444,392✔
573
  if (e->k == VJMP)
1,444,392✔
574
    jmp_append(fs, &e->t, e->u.s.info);  /* Add it to the true jump list. */
224,286✔
575
  if (expr_hasjump(e)) {  /* Discharge expression with branches. */
1,444,392✔
576
    BCPos jend, jfalse = NO_JMP, jtrue = NO_JMP;
288,889✔
577
    if (jmp_novalue(fs, e->t) || jmp_novalue(fs, e->f)) {
288,889✔
578
      BCPos jval = (e->k == VJMP) ? NO_JMP : bcemit_jmp(fs);
260,599✔
579
      jfalse = bcemit_AD(fs, BC_KPRI, reg, VKFALSE);
260,599✔
580
      bcemit_AJ(fs, BC_JMP, fs->freereg, 1);
260,599✔
581
      jtrue = bcemit_AD(fs, BC_KPRI, reg, VKTRUE);
260,599✔
582
      jmp_tohere(fs, jval);
260,599✔
583
    }
584
    jend = fs->pc;
288,889✔
585
    fs->lasttarget = jend;
288,889✔
586
    jmp_patchval(fs, e->f, jend, reg, jfalse);
288,889✔
587
    jmp_patchval(fs, e->t, jend, reg, jtrue);
288,889✔
588
  }
589
  e->f = e->t = NO_JMP;
1,444,392✔
590
  e->u.s.info = reg;
1,444,392✔
591
  e->k = VNONRELOC;
1,444,392✔
592
}
1,444,392✔
593

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

603
/* Discharge an expression to any register. */
604
static BCReg expr_toanyreg(FuncState *fs, ExpDesc *e)
986,232✔
605
{
606
  expr_discharge(fs, e);
986,232✔
607
  if (e->k == VNONRELOC) {
986,232✔
608
    if (!expr_hasjump(e)) return e->u.s.info;  /* Already in a register. */
357,765✔
609
    if (e->u.s.info >= fs->nactvar) {
948✔
610
      expr_toreg(fs, e, e->u.s.info);  /* Discharge to temp. register. */
930✔
611
      return e->u.s.info;
930✔
612
    }
613
  }
614
  expr_tonextreg(fs, e);  /* Discharge to next register. */
628,485✔
615
  return e->u.s.info;
628,485✔
616
}
617

618
/* Partially discharge expression to a value. */
619
static void expr_toval(FuncState *fs, ExpDesc *e)
616,220✔
620
{
621
  if (expr_hasjump(e))
616,220✔
622
    expr_toanyreg(fs, e);
10,786✔
623
  else
624
    expr_discharge(fs, e);
605,434✔
625
}
616,220✔
626

627
/* Emit store for LHS expression. */
628
static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e)
409,076✔
629
{
630
  BCIns ins;
409,076✔
631
  if (var->k == VLOCAL) {
409,076✔
632
    fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW;
267,251✔
633
    expr_free(fs, e);
267,251✔
634
    expr_toreg(fs, e, var->u.s.info);
267,251✔
635
    return;
267,251✔
636
  } else if (var->k == VUPVAL) {
141,825✔
637
    fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW;
553✔
638
    expr_toval(fs, e);
553✔
639
    if (e->k <= VKTRUE)
553✔
640
      ins = BCINS_AD(BC_USETP, var->u.s.info, const_pri(e));
54✔
641
    else if (e->k == VKSTR)
499✔
642
      ins = BCINS_AD(BC_USETS, var->u.s.info, const_str(fs, e));
10✔
643
    else if (e->k == VKNUM)
489✔
644
      ins = BCINS_AD(BC_USETN, var->u.s.info, const_num(fs, e));
79✔
645
    else
646
      ins = BCINS_AD(BC_USETV, var->u.s.info, expr_toanyreg(fs, e));
410✔
647
  } else if (var->k == VGLOBAL) {
141,272✔
648
    BCReg ra = expr_toanyreg(fs, e);
126,062✔
649
    ins = BCINS_AD(BC_GSET, ra, const_str(fs, var));
126,062✔
650
  } else {
651
    BCReg ra, rc;
15,210✔
652
    lj_assertFS(var->k == VINDEXED, "bad expr type %d", var->k);
15,210✔
653
    ra = expr_toanyreg(fs, e);
15,210✔
654
    rc = var->u.s.aux;
15,210✔
655
    if ((int32_t)rc < 0) {
15,210✔
656
      ins = BCINS_ABC(BC_TSETS, ra, var->u.s.info, ~rc);
10,033✔
657
    } else if (rc > BCMAX_C) {
5,177✔
658
      ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1));
1,654✔
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);
3,523✔
667
    }
668
  }
669
  bcemit_INS(fs, ins);
141,825✔
670
  expr_free(fs, e);
141,825✔
671
}
672

673
/* Emit method lookup expression. */
674
static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key)
4,996✔
675
{
676
  BCReg idx, func, obj = expr_toanyreg(fs, e);
4,996✔
677
  expr_free(fs, e);
4,996✔
678
  func = fs->freereg;
4,996✔
679
  bcemit_AD(fs, BC_MOV, func+1+LJ_FR2, obj);  /* Copy object to 1st argument. */
4,996✔
680
  lj_assertFS(expr_isstrk(key), "bad usage");
4,996✔
681
  idx = const_str(fs, key);
4,996✔
682
  if (idx <= BCMAX_C) {
4,996✔
683
    bcreg_reserve(fs, 2+LJ_FR2);
4,990✔
684
    bcemit_ABC(fs, BC_TGETS, func, obj, idx);
4,990✔
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;
4,996✔
692
  e->k = VNONRELOC;
4,996✔
693
}
4,996✔
694

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

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

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

721
/* Emit conditional branch. */
722
static BCPos bcemit_branch(FuncState *fs, ExpDesc *e, int cond)
91,319✔
723
{
724
  BCPos pc;
91,319✔
725
  if (e->k == VRELOCABLE) {
91,319✔
726
    BCIns *ip = bcptr(fs, e);
46,503✔
727
    if (bc_op(*ip) == BC_NOT) {
46,503✔
728
      *ip = BCINS_AD(cond ? BC_ISF : BC_IST, 0, bc_d(*ip));
44,699✔
729
      return bcemit_jmp(fs);
44,699✔
730
    }
731
  }
732
  if (e->k != VNONRELOC) {
46,620✔
733
    bcreg_reserve(fs, 1);
1,806✔
734
    expr_toreg_nobranch(fs, e, fs->freereg-1);
1,806✔
735
  }
736
  bcemit_AD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info);
78,705✔
737
  pc = bcemit_jmp(fs);
46,620✔
738
  expr_free(fs, e);
46,620✔
739
  return pc;
740
}
741

742
/* Emit branch on true condition. */
743
static void bcemit_branch_t(FuncState *fs, ExpDesc *e)
191,363✔
744
{
745
  BCPos pc;
191,363✔
746
  expr_discharge(fs, e);
191,363✔
747
  if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE)
191,363✔
748
    pc = NO_JMP;  /* Never jump. */
749
  else if (e->k == VJMP)
176,569✔
750
    invertcond(fs, e), pc = e->u.s.info;
81,030✔
751
  else if (e->k == VKFALSE || e->k == VKNIL)
95,539✔
752
    expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs);
22,866✔
753
  else
754
    pc = bcemit_branch(fs, e, 0);
72,673✔
755
  jmp_append(fs, &e->f, pc);
191,363✔
756
  jmp_tohere(fs, e->t);
191,363✔
757
  e->t = NO_JMP;
191,363✔
758
}
191,363✔
759

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

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

780
/* Try constant-folding of arithmetic operators. */
781
static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2)
13,321✔
782
{
783
  TValue o;
13,321✔
784
  lua_Number n;
13,321✔
785
  if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0;
13,321✔
786
  n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD);
1,016✔
787
  setnumV(&o, n);
1,016✔
788
  if (tvisnan(&o) || tvismzero(&o)) return 0;  /* Avoid NaN and -0 as consts. */
1,016✔
789
  if (LJ_DUALNUM) {
999✔
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);
999✔
797
  return 1;
999✔
798
}
799

800
/* Emit arithmetic operator. */
801
static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
13,321✔
802
{
803
  BCReg rb, rc, t;
13,321✔
804
  uint32_t op;
13,321✔
805
  if (foldarith(opr, e1, e2))
13,321✔
806
    return;
807
  if (opr == OPR_POW) {
12,322✔
808
    op = BC_POW;
75✔
809
    rc = expr_toanyreg(fs, e2);
75✔
810
    rb = expr_toanyreg(fs, e1);
75✔
811
  } else {
812
    op = opr-OPR_ADD+BC_ADDVV;
12,247✔
813
    /* Must discharge 2nd operand first since VINDEXED might free regs. */
814
    expr_toval(fs, e2);
12,247✔
815
    if (expr_isnumk(e2) && (rc = const_num(fs, e2)) <= BCMAX_C)
12,247✔
816
      op -= BC_ADDVV-BC_ADDVN;
9,066✔
817
    else
818
      rc = expr_toanyreg(fs, e2);
3,181✔
819
    /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */
820
    lj_assertFS(expr_isnumk(e1) || e1->k == VNONRELOC,
12,247✔
821
                "bad expr type %d", e1->k);
822
    expr_toval(fs, e1);
12,247✔
823
    /* Avoid two consts to satisfy bytecode constraints. */
824
    if (expr_isnumk(e1) && !expr_isnumk(e2) &&
12,247✔
825
        (t = const_num(fs, e1)) <= BCMAX_B) {
1,173✔
826
      rb = rc; rc = t; op -= BC_ADDVV-BC_ADDNV;
1,173✔
827
    } else {
828
      rb = expr_toanyreg(fs, e1);
11,074✔
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--;
12,322✔
833
  if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--;
12,322✔
834
  e1->u.s.info = bcemit_ABC(fs, op, 0, rb, rc);
12,322✔
835
  e1->k = VRELOCABLE;
12,322✔
836
}
837

838
/* Emit comparison operator. */
839
static void bcemit_comp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
338,700✔
840
{
841
  ExpDesc *eret = e1;
338,700✔
842
  BCIns ins;
338,700✔
843
  expr_toval(fs, e1);
338,700✔
844
  if (opr == OPR_EQ || opr == OPR_NE) {
338,700✔
845
    BCOp op = opr == OPR_EQ ? BC_ISEQV : BC_ISNEV;
140,681✔
846
    BCReg ra;
140,681✔
847
    if (expr_isk(e1)) { e1 = e2; e2 = eret; }  /* Need constant in 2nd arg. */
140,681✔
848
    ra = expr_toanyreg(fs, e1);  /* First arg must be in a reg. */
140,681✔
849
    expr_toval(fs, e2);
140,681✔
850
    switch (e2->k) {
140,681✔
851
    case VKNIL: case VKFALSE: case VKTRUE:
47,141✔
852
      ins = BCINS_AD(op+(BC_ISEQP-BC_ISEQV), ra, const_pri(e2));
47,141✔
853
      break;
47,141✔
854
    case VKSTR:
2,202✔
855
      ins = BCINS_AD(op+(BC_ISEQS-BC_ISEQV), ra, const_str(fs, e2));
2,202✔
856
      break;
2,202✔
857
    case VKNUM:
3,030✔
858
      ins = BCINS_AD(op+(BC_ISEQN-BC_ISEQV), ra, const_num(fs, e2));
3,030✔
859
      break;
3,030✔
860
    default:
88,308✔
861
      ins = BCINS_AD(op, ra, expr_toanyreg(fs, e2));
88,308✔
862
      break;
88,308✔
863
    }
864
  } else {
865
    uint32_t op = opr-OPR_LT+BC_ISLT;
198,019✔
866
    BCReg ra, rd;
198,019✔
867
    if ((op-BC_ISLT) & 1) {  /* GT -> LT, GE -> LE */
198,019✔
868
      e1 = e2; e2 = eret;  /* Swap operands. */
99,089✔
869
      op = ((op-BC_ISLT)^3)+BC_ISLT;
99,089✔
870
      expr_toval(fs, e1);
99,089✔
871
      ra = expr_toanyreg(fs, e1);
99,089✔
872
      rd = expr_toanyreg(fs, e2);
99,089✔
873
    } else {
874
      rd = expr_toanyreg(fs, e2);
98,930✔
875
      ra = expr_toanyreg(fs, e1);
98,930✔
876
    }
877
    ins = BCINS_AD(op, ra, rd);
198,019✔
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--;
338,700✔
881
  if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--;
338,700✔
882
  bcemit_INS(fs, ins);
338,700✔
883
  eret->u.s.info = bcemit_jmp(fs);
338,700✔
884
  eret->k = VJMP;
338,700✔
885
}
338,700✔
886

887
/* Fixup left side of binary operator. */
888
static void bcemit_binop_left(FuncState *fs, BinOpr op, ExpDesc *e)
529,787✔
889
{
890
  if (op == OPR_AND) {
529,787✔
891
    bcemit_branch_t(fs, e);
86,435✔
892
  } else if (op == OPR_OR) {
443,352✔
893
    bcemit_branch_f(fs, e);
86,831✔
894
  } else if (op == OPR_CONCAT) {
356,521✔
895
    expr_tonextreg(fs, e);
4,234✔
896
  } else if (op == OPR_EQ || op == OPR_NE) {
352,287✔
897
    if (!expr_isk_nojump(e)) expr_toanyreg(fs, e);
140,685✔
898
  } else {
899
    if (!expr_isnumk_nojump(e)) expr_toanyreg(fs, e);
211,602✔
900
  }
901
}
529,787✔
902

903
/* Emit binary operator. */
904
static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2)
529,323✔
905
{
906
  if (op <= OPR_POW) {
529,323✔
907
    bcemit_arith(fs, op, e1, e2);
13,321✔
908
  } else if (op == OPR_AND) {
516,002✔
909
    lj_assertFS(e1->t == NO_JMP, "jump list not closed");
86,435✔
910
    expr_discharge(fs, e2);
86,435✔
911
    jmp_append(fs, &e2->f, e1->f);
86,435✔
912
    *e1 = *e2;
86,435✔
913
  } else if (op == OPR_OR) {
429,567✔
914
    lj_assertFS(e1->f == NO_JMP, "jump list not closed");
86,831✔
915
    expr_discharge(fs, e2);
86,831✔
916
    jmp_append(fs, &e2->t, e1->t);
86,831✔
917
    *e1 = *e2;
86,831✔
918
  } else if (op == OPR_CONCAT) {
342,736✔
919
    expr_toval(fs, e2);
4,036✔
920
    if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) {
4,036✔
921
      lj_assertFS(e1->u.s.info == bc_b(*bcptr(fs, e2))-1,
1,279✔
922
                  "bad CAT stack layout");
923
      expr_free(fs, e1);
1,279✔
924
      setbc_b(bcptr(fs, e2), e1->u.s.info);
1,279✔
925
      e1->u.s.info = e2->u.s.info;
1,279✔
926
    } else {
927
      expr_tonextreg(fs, e2);
2,757✔
928
      expr_free(fs, e2);
2,757✔
929
      expr_free(fs, e1);
2,757✔
930
      e1->u.s.info = bcemit_ABC(fs, BC_CAT, 0, e1->u.s.info, e2->u.s.info);
2,757✔
931
    }
932
    e1->k = VRELOCABLE;
4,036✔
933
  } else {
934
    lj_assertFS(op == OPR_NE || op == OPR_EQ ||
338,700✔
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);
338,700✔
938
  }
939
}
529,323✔
940

941
/* Emit unary operator. */
942
static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
299,912✔
943
{
944
  if (op == BC_NOT) {
299,912✔
945
    /* Swap true and false lists. */
946
    { BCPos temp = e->f; e->f = e->t; e->t = temp; }
296,388✔
947
    jmp_dropval(fs, e->f);
296,388✔
948
    jmp_dropval(fs, e->t);
296,388✔
949
    expr_discharge(fs, e);
296,388✔
950
    if (e->k == VKNIL || e->k == VKFALSE) {
296,388✔
951
      e->k = VKTRUE;
35,858✔
952
      return;
35,858✔
953
    } else if (expr_isk(e) || (LJ_HASFFI && e->k == VKCDATA)) {
260,530✔
954
      e->k = VKFALSE;
3,090✔
955
      return;
3,090✔
956
    } else if (e->k == VJMP) {
257,440✔
957
      invertcond(fs, e);
118,929✔
958
      return;
118,929✔
959
    } else if (e->k == VRELOCABLE) {
138,511✔
960
      bcreg_reserve(fs, 1);
20,206✔
961
      setbc_a(bcptr(fs, e), fs->freereg-1);
20,206✔
962
      e->u.s.info = fs->freereg-1;
20,206✔
963
      e->k = VNONRELOC;
20,206✔
964
    } else {
965
      lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k);
966
    }
967
  } else {
968
    lj_assertFS(op == BC_UNM || op == BC_LEN, "bad unop %d", op);
3,524✔
969
    if (op == BC_UNM && !expr_hasjump(e)) {  /* Constant-fold negations. */
3,524✔
970
#if LJ_HASFFI
971
      if (e->k == VKCDATA) {  /* Fold in-place since cdata is not interned. */
2,339✔
972
        GCcdata *cd = cdataV(&e->u.nval);
4✔
973
        int64_t *p = (int64_t *)cdataptr(cd);
4✔
974
        if (cd->ctypeid == CTID_COMPLEX_DOUBLE)
4✔
975
          p[1] ^= (int64_t)U64x(80000000,00000000);
×
976
        else
977
          *p = -*p;
4✔
978
        return;
4✔
979
      } else
980
#endif
981
      if (expr_isnumk(e) && !expr_numiszero(e)) {  /* Avoid folding to -0. */
2,335✔
982
        TValue *o = expr_numtv(e);
2,195✔
983
        if (tvisint(o)) {
2,195✔
984
          int32_t k = intV(o);
985
          if (k == -k)
986
            setnumV(o, -(lua_Number)k);
987
          else
988
            setintV(o, -k);
989
          return;
990
        } else {
991
          o->u64 ^= U64x(80000000,00000000);
2,195✔
992
          return;
2,195✔
993
        }
994
      }
995
    }
996
    expr_toanyreg(fs, e);
1,325✔
997
  }
998
  expr_free(fs, e);
139,836✔
999
  e->u.s.info = bcemit_AD(fs, op, 0, e->u.s.info);
139,836✔
1000
  e->k = VRELOCABLE;
139,836✔
1001
}
1002

1003
/* -- Lexer support ------------------------------------------------------- */
1004

1005
/* Check and consume optional token. */
1006
static int lex_opt(LexState *ls, LexToken tok)
2,957,997✔
1007
{
1008
  if (ls->tok == tok) {
2,957,997✔
1009
    lj_lex_next(ls);
870,715✔
1010
    return 1;
70,781✔
1011
  }
1012
  return 0;
1013
}
1014

1015
/* Check and consume token. */
1016
static void lex_check(LexState *ls, LexToken tok)
618,560✔
1017
{
1018
  if (ls->tok != tok)
618,560✔
1019
    err_token(ls, tok);
3,687✔
1020
  lj_lex_next(ls);
614,873✔
1021
}
614,856✔
1022

1023
/* Check for matching token. */
1024
static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line)
799,308✔
1025
{
1026
  if (!lex_opt(ls, what)) {
799,308✔
1027
    if (line == ls->linenumber) {
965✔
1028
      err_token(ls, what);
681✔
1029
    } else {
1030
      const char *swhat = lj_lex_token2str(ls, what);
284✔
1031
      const char *swho = lj_lex_token2str(ls, who);
284✔
1032
      lj_lex_error(ls, ls->tok, LJ_ERR_XMATCH, swhat, swho, line);
284✔
1033
    }
1034
  }
1035
}
798,335✔
1036

1037
/* Check for string token. */
1038
static GCstr *lex_str(LexState *ls)
1,099,146✔
1039
{
1040
  GCstr *s;
1,099,146✔
1041
  if (ls->tok != TK_name && (LJ_52 || ls->tok != TK_goto))
1,099,146✔
1042
    err_token(ls, TK_name);
220✔
1043
  s = strV(&ls->tokval);
1,098,926✔
1044
  lj_lex_next(ls);
1,098,926✔
1045
  return s;
1,098,926✔
1046
}
1047

1048
/* -- Variable handling --------------------------------------------------- */
1049

1050
#define var_get(ls, fs, i)        ((ls)->vstack[(fs)->varmap[(i)]])
1051

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

1072
#define var_new_lit(ls, n, v) \
1073
  var_new(ls, (n), lj_parse_keepstr(ls, "" v, sizeof(v)-1))
1074

1075
#define var_new_fixed(ls, n, vn) \
1076
  var_new(ls, (n), (GCstr *)(uintptr_t)(vn))
1077

1078
/* Add local variables. */
1079
static void var_add(LexState *ls, BCReg nvars)
83,914✔
1080
{
1081
  FuncState *fs = ls->fs;
83,914✔
1082
  BCReg nactvar = fs->nactvar;
83,914✔
1083
  while (nvars--) {
183,653✔
1084
    VarInfo *v = &var_get(ls, fs, nactvar);
99,739✔
1085
    v->startpc = fs->pc;
99,739✔
1086
    v->slot = nactvar++;
99,739✔
1087
    v->info = 0;
99,739✔
1088
  }
1089
  fs->nactvar = nactvar;
83,914✔
1090
}
1091

1092
/* Remove local variables. */
1093
static void var_remove(LexState *ls, BCReg tolevel)
247,075✔
1094
{
1095
  FuncState *fs = ls->fs;
247,075✔
1096
  while (fs->nactvar > tolevel)
342,219✔
1097
    var_get(ls, fs, --fs->nactvar).endpc = fs->pc;
95,144✔
1098
}
1099

1100
/* Lookup local variable name. */
1101
static BCReg var_lookup_local(FuncState *fs, GCstr *n)
958,912✔
1102
{
1103
  int i;
958,912✔
1104
  for (i = fs->nactvar-1; i >= 0; i--) {
2,753,091✔
1105
    if (n == strref(var_get(fs->ls, fs, i).name))
2,282,346✔
1106
      return (BCReg)i;
488,167✔
1107
  }
1108
  return (BCReg)-1;  /* Not found. */
1109
}
1110

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

1127
/* Forward declaration. */
1128
static void fscope_uvmark(FuncState *fs, BCReg level);
1129

1130
/* Recursively lookup variables in enclosing functions. */
1131
static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first)
1,372,665✔
1132
{
1133
  if (fs) {
1,372,665✔
1134
    BCReg reg = var_lookup_local(fs, name);
958,912✔
1135
    if ((int32_t)reg >= 0) {  /* Local in this function? */
958,912✔
1136
      expr_init(e, VLOCAL, reg);
488,167✔
1137
      if (!first)
488,167✔
1138
        fscope_uvmark(fs, reg);  /* Scope now has an upvalue. */
501,678✔
1139
      return (MSize)(e->u.s.aux = (uint32_t)fs->varmap[reg]);
488,167✔
1140
    } else {
1141
      MSize vidx = var_lookup_(fs->prev, name, e, 0);  /* Var in outer func? */
470,745✔
1142
      if ((int32_t)vidx >= 0) {  /* Yes, make it an upvalue here. */
470,685✔
1143
        e->u.s.info = (uint8_t)var_lookup_uv(fs, vidx, e);
15,942✔
1144
        e->k = VUPVAL;
15,941✔
1145
        return vidx;
15,941✔
1146
      }
1147
    }
1148
  } else {  /* Not found in any function, must be a global. */
1149
    expr_init(e, VGLOBAL, 0);
413,753✔
1150
    e->u.sval = name;
413,753✔
1151
  }
1152
  return (MSize)-1;  /* Global. */
1153
}
1154

1155
/* Lookup variable name. */
1156
#define var_lookup(ls, e) \
1157
  var_lookup_((ls)->fs, lex_str(ls), (e), 1)
1158

1159
/* -- Goto an label handling ---------------------------------------------- */
1160

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

1182
#define gola_isgoto(v)                ((v)->info & VSTACK_GOTO)
1183
#define gola_islabel(v)                ((v)->info & VSTACK_LABEL)
1184
#define gola_isgotolabel(v)        ((v)->info & (VSTACK_GOTO|VSTACK_LABEL))
1185

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

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

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

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

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

1279
/* -- Scope handling ------------------------------------------------------ */
1280

1281
/* Begin a scope. */
1282
static void fscope_begin(FuncState *fs, FuncScope *bl, int flags)
247,950✔
1283
{
1284
  bl->nactvar = (uint8_t)fs->nactvar;
247,950✔
1285
  bl->flags = flags;
247,950✔
1286
  bl->vstart = fs->ls->vtop;
247,950✔
1287
  bl->prev = fs->bl;
247,950✔
1288
  fs->bl = bl;
247,950✔
1289
  lj_assertFS(fs->freereg == fs->nactvar, "bad regalloc");
247,950✔
1290
}
1291

1292
/* End a scope. */
1293
static void fscope_end(FuncState *fs)
247,075✔
1294
{
1295
  FuncScope *bl = fs->bl;
247,075✔
1296
  LexState *ls = fs->ls;
247,075✔
1297
  fs->bl = bl->prev;
247,075✔
1298
  var_remove(ls, bl->nactvar);
247,075✔
1299
  fs->freereg = fs->nactvar;
247,075✔
1300
  lj_assertFS(bl->nactvar == fs->nactvar, "bad regalloc");
247,075✔
1301
  if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL)
247,075✔
1302
    bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0);
117✔
1303
  if ((bl->flags & FSCOPE_BREAK)) {
247,075✔
1304
    if ((bl->flags & FSCOPE_LOOP)) {
115,415✔
1305
      MSize idx = gola_new(ls, NAME_BREAK, VSTACK_LABEL, fs->pc);
49,366✔
1306
      ls->vtop = idx;  /* Drop break label immediately. */
49,366✔
1307
      gola_resolve(ls, bl, idx);
49,366✔
1308
    } else {  /* Need the fixup step to propagate the breaks. */
1309
      gola_fixup(ls, bl);
66,049✔
1310
      return;
66,049✔
1311
    }
1312
  }
1313
  if ((bl->flags & FSCOPE_GOLA)) {
181,026✔
1314
    gola_fixup(ls, bl);
27✔
1315
  }
1316
}
1317

1318
/* Mark scope as having an upvalue. */
1319
static void fscope_uvmark(FuncState *fs, BCReg level)
13,511✔
1320
{
1321
  FuncScope *bl;
13,511✔
1322
  for (bl = fs->bl; bl && bl->nactvar > level; bl = bl->prev)
13,575✔
1323
    ;
64✔
1324
  if (bl)
13,511✔
1325
    bl->flags |= FSCOPE_UPVAL;
13,511✔
1326
}
1327

1328
/* -- Function state management ------------------------------------------- */
1329

1330
/* Fixup bytecode for prototype. */
1331
static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n)
50,881✔
1332
{
1333
  BCInsLine *base = fs->bcbase;
50,881✔
1334
  MSize i;
50,881✔
1335
  pt->sizebc = n;
50,881✔
1336
  bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF,
101,762✔
1337
                   fs->framesize, 0);
1338
  for (i = 1; i < n; i++)
3,679,712✔
1339
    bc[i] = base[i].ins;
3,628,831✔
1340
}
1341

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

1359
/* Fixup constants for prototype. */
1360
static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr)
50,881✔
1361
{
1362
  GCtab *kt;
50,881✔
1363
  TValue *array;
50,881✔
1364
  Node *node;
50,881✔
1365
  MSize i, hmask;
50,881✔
1366
  checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants");
50,881✔
1367
  checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants");
50,880✔
1368
  setmref(pt->k, kptr);
50,879✔
1369
  pt->sizekn = fs->nkn;
50,879✔
1370
  pt->sizekgc = fs->nkgc;
50,879✔
1371
  kt = fs->kt;
50,879✔
1372
  array = tvref(kt->array);
50,879✔
1373
  for (i = 0; i < kt->asize; i++)
55,112✔
1374
    if (tvhaskslot(&array[i])) {
4,233✔
1375
      TValue *tv = &((TValue *)kptr)[tvkslot(&array[i])];
1,607✔
1376
      if (LJ_DUALNUM)
1,607✔
1377
        setintV(tv, (int32_t)i);
1378
      else
1379
        setnumV(tv, (lua_Number)i);
1,607✔
1380
    }
1381
  node = noderef(kt->node);
50,879✔
1382
  hmask = kt->hmask;
50,879✔
1383
  for (i = 0; i <= hmask; i++) {
1,307,322✔
1384
    Node *n = &node[i];
1,256,443✔
1385
    if (tvhaskslot(&n->val)) {
1,256,443✔
1386
      ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val);
338,217✔
1387
      lj_assertFS(!tvisint(&n->key), "unexpected integer key");
338,217✔
1388
      if (tvisnum(&n->key)) {
338,217✔
1389
        TValue *tv = &((TValue *)kptr)[kidx];
71,929✔
1390
        if (LJ_DUALNUM) {
71,929✔
1391
          lua_Number nn = numV(&n->key);
1392
          int32_t k = lj_num2int(nn);
1393
          lj_assertFS(!tvismzero(&n->key), "unexpected -0 key");
1394
          if ((lua_Number)k == nn)
1395
            setintV(tv, k);
1396
          else
1397
            *tv = n->key;
1398
        } else {
1399
          *tv = n->key;
71,929✔
1400
        }
1401
      } else {
1402
        GCobj *o = gcV(&n->key);
266,288✔
1403
        setgcref(((GCRef *)kptr)[~kidx], o);
266,288✔
1404
        lj_gc_objbarrier(fs->L, pt, o);
266,288✔
1405
        if (tvisproto(&n->key))
266,288✔
1406
          fs_fixup_uv2(fs, gco2pt(o));
12,321✔
1407
      }
1408
    }
1409
  }
1410
}
50,879✔
1411

1412
/* Fixup upvalues for prototype, step #1. */
1413
static void fs_fixup_uv1(FuncState *fs, GCproto *pt, uint16_t *uv)
50,879✔
1414
{
1415
  setmref(pt->uv, uv);
50,879✔
1416
  pt->sizeuv = fs->nuv;
50,879✔
1417
  memcpy(uv, fs->uvtmp, fs->nuv*sizeof(VarIndex));
50,879✔
1418
}
1419

1420
#ifndef LUAJIT_DISABLE_DEBUGINFO
1421
/* Prepare lineinfo for prototype. */
1422
static size_t fs_prep_line(FuncState *fs, BCLine numline)
50,881✔
1423
{
1424
  return (fs->pc-1) << (numline < 256 ? 0 : numline < 65536 ? 1 : 2);
163✔
1425
}
1426

1427
/* Fixup lineinfo for prototype. */
1428
static void fs_fixup_line(FuncState *fs, GCproto *pt,
50,879✔
1429
                          void *lineinfo, BCLine numline)
1430
{
1431
  BCInsLine *base = fs->bcbase + 1;
50,879✔
1432
  BCLine first = fs->linedefined;
50,879✔
1433
  MSize i = 0, n = fs->pc-1;
50,879✔
1434
  pt->firstline = fs->linedefined;
50,879✔
1435
  pt->numline = numline;
50,879✔
1436
  setmref(pt->lineinfo, lineinfo);
50,879✔
1437
  if (LJ_LIKELY(numline < 256)) {
50,879✔
1438
    uint8_t *li = (uint8_t *)lineinfo;
3,324,574✔
1439
    do {
3,324,574✔
1440
      BCLine delta = base[i].line - first;
3,324,574✔
1441
      lj_assertFS(delta >= 0 && delta < 256, "bad line delta");
3,324,574✔
1442
      li[i] = (uint8_t)delta;
3,324,574✔
1443
    } while (++i < n);
3,324,574✔
1444
  } else if (LJ_LIKELY(numline < 65536)) {
161✔
1445
    uint16_t *li = (uint16_t *)lineinfo;
41,964✔
1446
    do {
41,964✔
1447
      BCLine delta = base[i].line - first;
41,964✔
1448
      lj_assertFS(delta >= 0 && delta < 65536, "bad line delta");
41,964✔
1449
      li[i] = (uint16_t)delta;
41,964✔
1450
    } while (++i < n);
41,964✔
1451
  } else {
1452
    uint32_t *li = (uint32_t *)lineinfo;
131,215✔
1453
    do {
131,215✔
1454
      BCLine delta = base[i].line - first;
131,215✔
1455
      lj_assertFS(delta >= 0, "bad line delta");
131,215✔
1456
      li[i] = (uint32_t)delta;
131,215✔
1457
    } while (++i < n);
131,215✔
1458
  }
1459
}
50,879✔
1460

1461
/* Prepare variable info for prototype. */
1462
static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
50,881✔
1463
{
1464
  VarInfo *vs =ls->vstack, *ve;
50,881✔
1465
  MSize i, n;
50,881✔
1466
  BCPos lastpc;
50,881✔
1467
  lj_buf_reset(&ls->sb);  /* Copy to temp. string buffer. */
50,881✔
1468
  /* Store upvalue names. */
1469
  for (i = 0, n = fs->nuv; i < n; i++) {
60,379✔
1470
    GCstr *s = strref(vs[fs->uvmap[i]].name);
9,498✔
1471
    MSize len = s->len+1;
9,498✔
1472
    char *p = lj_buf_more(&ls->sb, len);
9,498✔
1473
    p = lj_buf_wmem(p, strdata(s), len);
9,498✔
1474
    setsbufP(&ls->sb, p);
9,498✔
1475
  }
1476
  *ofsvar = sbuflen(&ls->sb);
50,881✔
1477
  lastpc = 0;
50,881✔
1478
  /* Store local variable names and compressed ranges. */
1479
  for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) {
195,431✔
1480
    if (!gola_isgotolabel(vs)) {
144,550✔
1481
      GCstr *s = strref(vs->name);
95,140✔
1482
      BCPos startpc;
95,140✔
1483
      char *p;
95,140✔
1484
      if ((uintptr_t)s < VARNAME__MAX) {
95,140✔
1485
        p = lj_buf_more(&ls->sb, 1 + 2*5);
7,527✔
1486
        *p++ = (char)(uintptr_t)s;
7,527✔
1487
      } else {
1488
        MSize len = s->len+1;
87,613✔
1489
        p = lj_buf_more(&ls->sb, len + 2*5);
87,613✔
1490
        p = lj_buf_wmem(p, strdata(s), len);
87,613✔
1491
      }
1492
      startpc = vs->startpc;
95,140✔
1493
      p = lj_strfmt_wuleb128(p, startpc-lastpc);
95,140✔
1494
      p = lj_strfmt_wuleb128(p, vs->endpc-startpc);
95,140✔
1495
      setsbufP(&ls->sb, p);
95,140✔
1496
      lastpc = startpc;
95,140✔
1497
    }
1498
  }
1499
  lj_buf_putb(&ls->sb, '\0');  /* Terminator for varinfo. */
50,881✔
1500
  return sbuflen(&ls->sb);
50,881✔
1501
}
1502

1503
/* Fixup variable info for prototype. */
1504
static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar)
50,879✔
1505
{
1506
  setmref(pt->uvinfo, p);
50,879✔
1507
  setmref(pt->varinfo, (char *)p + ofsvar);
50,879✔
1508
  memcpy(p, sbufB(&ls->sb), sbuflen(&ls->sb));  /* Copy from temp. buffer. */
50,879✔
1509
}
1510
#else
1511

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

1520
#endif
1521

1522
/* Check if bytecode op returns. */
1523
static int bcopisret(BCOp op)
33,490✔
1524
{
1525
  switch (op) {
33,490✔
1526
  case BC_CALLMT: case BC_CALLT:
1527
  case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
1528
    return 1;
1529
  default:
1530
    return 0;
1531
  }
1532
}
1533

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

1572
/* Finish a FuncState and return the new prototype. */
1573
static GCproto *fs_finish(LexState *ls, BCLine line)
50,889✔
1574
{
1575
  lua_State *L = ls->L;
50,889✔
1576
  FuncState *fs = ls->fs;
50,889✔
1577
  BCLine numline = line - fs->linedefined;
50,889✔
1578
  size_t sizept, ofsk, ofsuv, ofsli, ofsdbg, ofsvar;
50,889✔
1579
  GCproto *pt;
50,889✔
1580

1581
  /* Apply final fixups. */
1582
  fs_fixup_ret(fs);
50,889✔
1583

1584
  /* Calculate total size of prototype including all colocated arrays. */
1585
  sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef);
50,881✔
1586
  sizept = (sizept + sizeof(TValue)-1) & ~(sizeof(TValue)-1);
50,881✔
1587
  ofsk = sizept; sizept += fs->nkn*sizeof(TValue);
50,881✔
1588
  ofsuv = sizept; sizept += ((fs->nuv+1)&~1)*2;
50,881✔
1589
  ofsli = sizept; sizept += fs_prep_line(fs, numline);
50,881✔
1590
  ofsdbg = sizept; sizept += fs_prep_var(ls, fs, &ofsvar);
50,881✔
1591

1592
  /* Allocate prototype and initialize its fields. */
1593
  pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept);
50,881✔
1594
  pt->gct = ~LJ_TPROTO;
50,881✔
1595
  pt->sizept = (MSize)sizept;
50,881✔
1596
  pt->trace = 0;
50,881✔
1597
  pt->flags = (uint8_t)(fs->flags & ~(PROTO_HAS_RETURN|PROTO_FIXUP_RETURN));
50,881✔
1598
  pt->numparams = fs->numparams;
50,881✔
1599
  pt->framesize = fs->framesize;
50,881✔
1600
  setgcref(pt->chunkname, obj2gco(ls->chunkname));
50,881✔
1601

1602
  /* Close potentially uninitialized gap between bc and kgc. */
1603
  *(uint32_t *)((char *)pt + ofsk - sizeof(GCRef)*(fs->nkgc+1)) = 0;
50,881✔
1604
  fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), fs->pc);
50,881✔
1605
  fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk));
50,881✔
1606
  fs_fixup_uv1(fs, pt, (uint16_t *)((char *)pt + ofsuv));
50,879✔
1607
  fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline);
50,879✔
1608
  fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar);
50,879✔
1609

1610
  lj_vmevent_send(L, BC,
50,879✔
1611
    setprotoV(L, L->top++, pt);
1612
  );
50,879✔
1613

1614
  /* Add a new prototype to the profiler. */
1615
#if LJ_HASMEMPROF
1616
  lj_memprof_add_proto(pt);
50,879✔
1617
#endif
1618
#if LJ_HASSYSPROF
1619
  lj_sysprof_add_proto(pt);
50,879✔
1620
#endif
1621

1622
  L->top--;  /* Pop table of constants. */
50,879✔
1623
  ls->vtop = fs->vbase;  /* Reset variable stack. */
50,879✔
1624
  ls->fs = fs->prev;
50,879✔
1625
  lj_assertL(ls->fs != NULL || ls->tok == TK_eof, "bad parser state");
50,879✔
1626
  return pt;
50,879✔
1627
}
1628

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

1654
/* -- Expressions --------------------------------------------------------- */
1655

1656
/* Forward declaration. */
1657
static void expr(LexState *ls, ExpDesc *v);
1658

1659
/* Return string expression. */
1660
static void expr_str(LexState *ls, ExpDesc *e)
104,483✔
1661
{
1662
  expr_init(e, VKSTR, 0);
104,483✔
1663
  e->u.sval = lex_str(ls);
208,966✔
1664
}
1665

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

1698
/* Parse index expression with named field. */
1699
static void expr_field(LexState *ls, ExpDesc *v)
22,410✔
1700
{
1701
  FuncState *fs = ls->fs;
22,410✔
1702
  ExpDesc key;
22,410✔
1703
  expr_toanyreg(fs, v);
22,410✔
1704
  lj_lex_next(ls);  /* Skip dot or colon. */
22,410✔
1705
  expr_str(ls, &key);
22,410✔
1706
  expr_index(fs, v, &key);
22,410✔
1707
}
22,410✔
1708

1709
/* Parse index expression with brackets. */
1710
static void expr_bracket(LexState *ls, ExpDesc *v)
8,667✔
1711
{
1712
  lj_lex_next(ls);  /* Skip '['. */
8,667✔
1713
  expr(ls, v);
17,334✔
1714
  expr_toval(ls->fs, v);
8,667✔
1715
  lex_check(ls, ']');
8,667✔
1716
}
8,667✔
1717

1718
/* Get value of constant expression. */
1719
static void expr_kvalue(FuncState *fs, TValue *v, ExpDesc *e)
372,290✔
1720
{
1721
  UNUSED(fs);
372,290✔
1722
  if (e->k <= VKTRUE) {
372,290✔
1723
    setpriV(v, ~(uint32_t)e->k);
679✔
1724
  } else if (e->k == VKSTR) {
371,611✔
1725
    setgcVraw(v, obj2gco(e->u.sval), LJ_TSTR);
260,834✔
1726
  } else {
1727
    lj_assertFS(tvisnumber(expr_numtv(e)), "bad number constant");
236,771✔
1728
    *v = *expr_numtv(e);
236,771✔
1729
  }
1730
}
1731

1732
/* Parse table constructor expression. */
1733
static void expr_table(LexState *ls, ExpDesc *e)
5,901✔
1734
{
1735
  FuncState *fs = ls->fs;
5,901✔
1736
  BCLine line = ls->linenumber;
5,901✔
1737
  GCtab *t = NULL;
5,901✔
1738
  int vcall = 0, needarr = 0, fixt = 0;
5,901✔
1739
  uint32_t narr = 1;  /* First array index. */
5,901✔
1740
  uint32_t nhash = 0;  /* Number of hash entries. */
5,901✔
1741
  BCReg freg = fs->freereg;
5,901✔
1742
  BCPos pc = bcemit_AD(fs, BC_TNEW, freg, 0);
5,901✔
1743
  expr_init(e, VNONRELOC, freg);
5,901✔
1744
  bcreg_reserve(fs, 1);
5,901✔
1745
  freg++;
5,901✔
1746
  lex_check(ls, '{');
5,901✔
1747
  while (ls->tok != '}') {
194,315✔
1748
    ExpDesc key, val;
191,165✔
1749
    vcall = 0;
191,165✔
1750
    if (ls->tok == '[') {
191,165✔
1751
      expr_bracket(ls, &key);  /* Already calls expr_toval. */
402✔
1752
      if (!expr_isk(&key)) expr_index(fs, e, &key);
402✔
1753
      if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++;
402✔
1754
      lex_check(ls, '=');
402✔
1755
    } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) &&
268,343✔
1756
               lj_lex_lookahead(ls) == '=') {
77,580✔
1757
      expr_str(ls, &key);
77,077✔
1758
      lex_check(ls, '=');
77,077✔
1759
      nhash++;
77,077✔
1760
    } else {
1761
      expr_init(&key, VKNUM, 0);
113,686✔
1762
      setintV(&key.u.nval, (int)narr);
113,686✔
1763
      narr++;
113,686✔
1764
      needarr = vcall = 1;
113,686✔
1765
    }
1766
    expr(ls, &val);
382,132✔
1767
    if (expr_isk(&key) && key.k != VKNIL &&
190,967✔
1768
        (key.k == VKSTR || expr_isk_nojump(&val))) {
113,618✔
1769
      TValue k, *v;
188,688✔
1770
      if (!t) {  /* Create template table on demand. */
188,688✔
1771
        BCReg kidx;
3,273✔
1772
        t = lj_tab_new(fs->L, needarr ? narr : 0, hsize2hbits(nhash));
4,961✔
1773
        kidx = const_gc(fs, obj2gco(t), LJ_TTAB);
3,273✔
1774
        fs->bcbase[pc].ins = BCINS_AD(BC_TDUP, freg-1, kidx);
3,273✔
1775
      }
1776
      vcall = 0;
188,688✔
1777
      expr_kvalue(fs, &k, &key);
188,688✔
1778
      v = lj_tab_set(fs->L, t, &k);
188,688✔
1779
      lj_gc_anybarriert(fs->L, t);
188,688✔
1780
      if (expr_isk_nojump(&val)) {  /* Add const key/value to template table. */
188,688✔
1781
        expr_kvalue(fs, v, &val);
183,602✔
1782
      } else {  /* Otherwise create dummy string key (avoids lj_tab_newkey). */
1783
        settabV(fs->L, v, t);  /* Preserve key with table itself as value. */
5,086✔
1784
        fixt = 1;   /* Fix this later, after all resizes. */
5,086✔
1785
        goto nonconst;
5,086✔
1786
      }
1787
    } else {
1788
    nonconst:
2,279✔
1789
      if (val.k != VCALL) { expr_toanyreg(fs, &val); vcall = 0; }
7,365✔
1790
      if (expr_isk(&key)) expr_index(fs, e, &key);
7,365✔
1791
      bcemit_store(fs, e, &val);
7,365✔
1792
    }
1793
    fs->freereg = freg;
190,967✔
1794
    if (!lex_opt(ls, ',') && !lex_opt(ls, ';')) break;
190,967✔
1795
  }
1796
  lex_match(ls, '}', '{', line);
5,703✔
1797
  if (vcall) {
5,701✔
1798
    BCInsLine *ilp = &fs->bcbase[fs->pc-1];
297✔
1799
    ExpDesc en;
297✔
1800
    lj_assertFS(bc_a(ilp->ins) == freg &&
297✔
1801
                bc_op(ilp->ins) == (narr > 256 ? BC_TSETV : BC_TSETB),
1802
                "bad CALL code generation");
1803
    expr_init(&en, VKNUM, 0);
297✔
1804
    en.u.nval.u32.lo = narr-1;
297✔
1805
    en.u.nval.u32.hi = 0x43300000;  /* Biased integer to avoid denormals. */
297✔
1806
    if (narr > 256) { fs->pc--; ilp--; }
297✔
1807
    ilp->ins = BCINS_AD(BC_TSETM, freg, const_num(fs, &en));
297✔
1808
    setbc_b(&ilp[-1].ins, 0);
297✔
1809
  }
1810
  if (pc == fs->pc-1) {  /* Make expr relocable if possible. */
5,701✔
1811
    e->u.s.info = pc;
3,931✔
1812
    fs->freereg--;
3,931✔
1813
    e->k = VRELOCABLE;
3,931✔
1814
  } else {
1815
    e->k = VNONRELOC;  /* May have been changed by expr_index. */
1,770✔
1816
  }
1817
  if (!t) {  /* Construct TNEW RD: hhhhhaaaaaaaaaaa. */
5,701✔
1818
    BCIns *ip = &fs->bcbase[pc].ins;
2,430✔
1819
    if (!needarr) narr = 0;
2,430✔
1820
    else if (narr < 3) narr = 3;
411✔
1821
    else if (narr > 0x7ff) narr = 0x7ff;
1822
    setbc_d(ip, narr|(hsize2hbits(nhash)<<11));
2,430✔
1823
  } else {
1824
    if (needarr && t->asize < narr)
3,271✔
1825
      lj_tab_reasize(fs->L, t, narr-1);
33✔
1826
    if (fixt) {  /* Fix value for dummy keys in template table. */
3,271✔
1827
      Node *node = noderef(t->node);
1,202✔
1828
      uint32_t i, hmask = t->hmask;
1,202✔
1829
      for (i = 0; i <= hmask; i++) {
8,224✔
1830
        Node *n = &node[i];
7,022✔
1831
        if (tvistab(&n->val)) {
7,022✔
1832
          lj_assertFS(tabV(&n->val) == t, "bad dummy key in template table");
5,086✔
1833
          setnilV(&n->val);  /* Turn value into nil. */
5,086✔
1834
        }
1835
      }
1836
    }
1837
    lj_gc_check(fs->L);
3,271✔
1838
  }
1839
}
5,701✔
1840

1841
/* Parse function parameters. */
1842
static BCReg parse_params(LexState *ls, int needself)
16,011✔
1843
{
1844
  FuncState *fs = ls->fs;
16,011✔
1845
  BCReg nparams = 0;
16,011✔
1846
  lex_check(ls, '(');
16,011✔
1847
  if (needself)
15,914✔
1848
    var_new_lit(ls, nparams++, "self");
31✔
1849
  if (ls->tok != ')') {
15,914✔
1850
    do {
24,270✔
1851
      if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) {
24,270✔
1852
        var_new(ls, nparams++, lex_str(ls));
23,823✔
1853
      } else if (ls->tok == TK_dots) {
447✔
1854
        lj_lex_next(ls);
391✔
1855
        fs->flags |= PROTO_VARARG;
391✔
1856
        break;
391✔
1857
      } else {
1858
        err_syntax(ls, LJ_ERR_XPARAM);
56✔
1859
      }
1860
    } while (lex_opt(ls, ','));
23,823✔
1861
  }
1862
  var_add(ls, nparams);
15,858✔
1863
  lj_assertFS(fs->nactvar == nparams, "bad regalloc");
15,858✔
1864
  bcreg_reserve(fs, nparams);
15,858✔
1865
  lex_check(ls, ')');
15,858✔
1866
  return nparams;
15,803✔
1867
}
1868

1869
/* Forward declaration. */
1870
static void parse_chunk(LexState *ls);
1871

1872
/* Parse body of a function. */
1873
static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
16,011✔
1874
{
1875
  FuncState fs, *pfs = ls->fs;
16,011✔
1876
  FuncScope bl;
16,011✔
1877
  GCproto *pt;
16,011✔
1878
  ptrdiff_t oldbase = pfs->bcbase - ls->bcstack;
16,011✔
1879
  fs_init(ls, &fs);
16,011✔
1880
  fscope_begin(&fs, &bl, 0);
16,011✔
1881
  fs.linedefined = line;
16,011✔
1882
  fs.numparams = (uint8_t)parse_params(ls, needself);
16,011✔
1883
  fs.bcbase = pfs->bcbase + pfs->pc;
15,803✔
1884
  fs.bclim = pfs->bclim - pfs->pc;
15,803✔
1885
  bcemit_AD(&fs, BC_FUNCF, 0, 0);  /* Placeholder. */
15,803✔
1886
  parse_chunk(ls);
15,803✔
1887
  if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line);
12,842✔
1888
  pt = fs_finish(ls, (ls->lastline = ls->linenumber));
12,346✔
1889
  pfs->bcbase = ls->bcstack + oldbase;  /* May have been reallocated. */
12,345✔
1890
  pfs->bclim = (BCPos)(ls->sizebcstack - oldbase);
12,345✔
1891
  /* Store new prototype in the constant array of the parent. */
1892
  expr_init(e, VRELOCABLE,
37,035✔
1893
            bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO)));
12,345✔
1894
#if LJ_HASFFI
1895
  pfs->flags |= (fs.flags & PROTO_FFI);
12,345✔
1896
#endif
1897
  if (!(pfs->flags & PROTO_CHILD)) {
12,345✔
1898
    if (pfs->flags & PROTO_HAS_RETURN)
6,317✔
1899
      pfs->flags |= PROTO_FIXUP_RETURN;
243✔
1900
    pfs->flags |= PROTO_CHILD;
6,317✔
1901
  }
1902
  lj_lex_next(ls);
12,345✔
1903
}
12,345✔
1904

1905
/* Parse expression list. Last expression is left open. */
1906
static BCReg expr_list(LexState *ls, ExpDesc *v)
657,507✔
1907
{
1908
  BCReg n = 1;
657,507✔
1909
  expr(ls, v);
1,331,731✔
1910
  while (lex_opt(ls, ',')) {
674,224✔
1911
    expr_tonextreg(ls->fs, v);
24,825✔
1912
    expr(ls, v);
49,644✔
1913
    n++;
24,819✔
1914
  }
1915
  return n;
649,399✔
1916
}
1917

1918
/* Parse function argument list. */
1919
static void parse_args(LexState *ls, ExpDesc *e)
290,234✔
1920
{
1921
  FuncState *fs = ls->fs;
290,234✔
1922
  ExpDesc args;
290,234✔
1923
  BCIns ins;
290,234✔
1924
  BCReg base;
290,234✔
1925
  BCLine line = ls->linenumber;
290,234✔
1926
  if (ls->tok == '(') {
290,234✔
1927
#if !LJ_52
1928
    if (line != ls->lastline)
289,106✔
1929
      err_syntax(ls, LJ_ERR_XAMBIG);
1✔
1930
#endif
1931
    lj_lex_next(ls);
289,105✔
1932
    if (ls->tok == ')') {  /* f(). */
289,105✔
1933
      args.k = VVOID;
100,334✔
1934
    } else {
1935
      expr_list(ls, &args);
188,771✔
1936
      if (args.k == VCALL)  /* f(a, b, g()) or f(a, b, ...). */
186,350✔
1937
        setbc_b(bcptr(fs, &args), 0);  /* Pass on multiple results. */
2,815✔
1938
    }
1939
    lex_match(ls, ')', '(', line);
286,684✔
1940
  } else if (ls->tok == '{') {
1,128✔
1941
    expr_table(ls, &args);
110✔
1942
  } else if (ls->tok == TK_string) {
1,018✔
1943
    expr_init(&args, VKSTR, 0);
1,017✔
1944
    args.u.sval = strV(&ls->tokval);
1,017✔
1945
    lj_lex_next(ls);
1,017✔
1946
  } else {
1947
    err_syntax(ls, LJ_ERR_XFUNARG);
1✔
1948
    return;  /* Silence compiler. */
1949
  }
1950
  lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k);
287,515✔
1951
  base = e->u.s.info;  /* Base register for call. */
287,515✔
1952
  if (args.k == VCALL) {
287,515✔
1953
    ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - LJ_FR2);
2,815✔
1954
  } else {
1955
    if (args.k != VVOID)
284,700✔
1956
      expr_tonextreg(fs, &args);
184,366✔
1957
    ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - LJ_FR2);
284,700✔
1958
  }
1959
  expr_init(e, VCALL, bcemit_INS(fs, ins));
287,515✔
1960
  e->u.s.aux = base;
287,515✔
1961
  fs->bcbase[fs->pc - 1].line = line;
287,515✔
1962
  fs->freereg = base+1;  /* Leave one result by default. */
287,515✔
1963
}
1964

1965
/* Parse primary expression. */
1966
static void expr_primary(LexState *ls, ExpDesc *v)
1,300,407✔
1967
{
1968
  FuncState *fs = ls->fs;
1,300,407✔
1969
  /* Parse prefix expression. */
1970
  if (ls->tok == '(') {
1,300,407✔
1971
    BCLine line = ls->linenumber;
399,768✔
1972
    lj_lex_next(ls);
399,768✔
1973
    expr(ls, v);
799,265✔
1974
    lex_match(ls, ')', '(', line);
399,497✔
1975
    expr_discharge(ls->fs, v);
399,351✔
1976
  } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) {
900,639✔
1977
    var_lookup(ls, v);
893,594✔
1978
  } else {
1979
    err_syntax(ls, LJ_ERR_XSYMBOL);
7,045✔
1980
  }
1981
  for (;;) {  /* Parse multiple expression suffixes. */
1,610,838✔
1982
    if (ls->tok == '.') {
1,610,838✔
1983
      expr_field(ls, v);
22,114✔
1984
    } else if (ls->tok == '[') {
1,588,724✔
1985
      ExpDesc key;
8,265✔
1986
      expr_toanyreg(fs, v);
8,265✔
1987
      expr_bracket(ls, &key);
8,265✔
1988
      expr_index(fs, v, &key);
8,265✔
1989
    } else if (ls->tok == ':') {
1,580,459✔
1990
      ExpDesc key;
4,996✔
1991
      lj_lex_next(ls);
4,996✔
1992
      expr_str(ls, &key);
4,996✔
1993
      bcemit_method(fs, v, &key);
4,996✔
1994
      parse_args(ls, v);
4,996✔
1995
    } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') {
1,575,463✔
1996
      expr_tonextreg(fs, v);
285,238✔
1997
      if (LJ_FR2) bcreg_reserve(fs, 1);
285,238✔
1998
      parse_args(ls, v);
285,238✔
1999
    } else {
2000
      break;
2001
    }
2002
  }
2003
}
1,290,225✔
2004

2005
/* Parse simple expression. */
2006
static void expr_simple(LexState *ls, ExpDesc *v)
1,920,157✔
2007
{
2008
  switch (ls->tok) {
1,920,157✔
2009
  case TK_number:
691,336✔
2010
    expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokval)) ? VKCDATA : VKNUM, 0);
691,336✔
2011
    copyTV(ls->L, &v->u.nval, &ls->tokval);
691,336✔
2012
    break;
2013
  case TK_string:
2014
    expr_init(v, VKSTR, 0);
213,038✔
2015
    v->u.sval = strV(&ls->tokval);
213,038✔
2016
    break;
213,038✔
2017
  case TK_nil:
2018
    expr_init(v, VKNIL, 0);
113,769✔
2019
    break;
2020
  case TK_true:
2021
    expr_init(v, VKTRUE, 0);
14,903✔
2022
    break;
2023
  case TK_false:
2024
    expr_init(v, VKFALSE, 0);
14,257✔
2025
    break;
2026
  case TK_dots: {  /* Vararg. */
542✔
2027
    FuncState *fs = ls->fs;
542✔
2028
    BCReg base;
542✔
2029
    checkcond(ls, fs->flags & PROTO_VARARG, LJ_ERR_XDOTS);
542✔
2030
    bcreg_reserve(fs, 1);
541✔
2031
    base = fs->freereg-1;
541✔
2032
    expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams));
541✔
2033
    v->u.s.aux = base;
541✔
2034
    break;
541✔
2035
  }
2036
  case '{':  /* Table constructor. */
5,791✔
2037
    expr_table(ls, v);
5,791✔
2038
    return;
5,791✔
2039
  case TK_function:
3,802✔
2040
    lj_lex_next(ls);
3,802✔
2041
    parse_body(ls, v, 0, ls->linenumber);
3,802✔
2042
    return;
3,802✔
2043
  default:
862,719✔
2044
    expr_primary(ls, v);
862,719✔
2045
    return;
862,719✔
2046
  }
2047
  lj_lex_next(ls);
1,047,844✔
2048
}
2049

2050
/* Manage syntactic levels to avoid blowing up the stack. */
2051
static void synlevel_begin(LexState *ls)
2,429,557✔
2052
{
2053
  if (++ls->level >= LJ_MAX_XLEVEL)
2,429,557✔
2054
    lj_lex_error(ls, 0, LJ_ERR_XLEVELS);
8✔
2055
}
2056

2057
#define synlevel_end(ls)        ((ls)->level--)
2058

2059
/* Convert token to binary operator. */
2060
static BinOpr token2binop(LexToken tok)
2,211,538✔
2061
{
2062
  switch (tok) {
2,211,538✔
2063
  case '+':        return OPR_ADD;
2064
  case '-':        return OPR_SUB;
3,791✔
2065
  case '*':        return OPR_MUL;
529✔
2066
  case '/':        return OPR_DIV;
147✔
2067
  case '%':        return OPR_MOD;
90✔
2068
  case '^':        return OPR_POW;
1,006✔
2069
  case TK_concat: return OPR_CONCAT;
4,234✔
2070
  case TK_ne:        return OPR_NE;
84,421✔
2071
  case TK_eq:        return OPR_EQ;
89,340✔
2072
  case '<':        return OPR_LT;
98,645✔
2073
  case TK_le:        return OPR_LE;
298✔
2074
  case '>':        return OPR_GT;
460✔
2075
  case TK_ge:        return OPR_GE;
98,652✔
2076
  case TK_and:        return OPR_AND;
102,929✔
2077
  case TK_or:        return OPR_OR;
103,244✔
2078
  default:        return OPR_NOBINOPR;
1,615,449✔
2079
  }
2080
}
2081

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

2094
#define UNARY_PRIORITY                8  /* Priority for unary operators. */
2095

2096
/* Forward declaration. */
2097
static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit);
2098

2099
/* Parse unary expression. */
2100
static void expr_unop(LexState *ls, ExpDesc *v)
2,220,069✔
2101
{
2102
  BCOp op;
2,220,069✔
2103
  if (ls->tok == TK_not) {
2,220,069✔
2104
    op = BC_NOT;
2105
  } else if (ls->tok == '-') {
1,923,681✔
2106
    op = BC_UNM;
2107
  } else if (ls->tok == '#') {
1,921,341✔
2108
    op = BC_LEN;
2109
  } else {
2110
    expr_simple(ls, v);
1,920,157✔
2111
    return;
1,920,157✔
2112
  }
2113
  lj_lex_next(ls);
299,912✔
2114
  expr_binop(ls, v, UNARY_PRIORITY);
299,912✔
2115
  bcemit_unop(ls->fs, op, v);
299,912✔
2116
}
2117

2118
/* Parse binary expressions with priority higher than the limit. */
2119
static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit)
2,220,075✔
2120
{
2121
  BinOpr op;
2,220,075✔
2122
  synlevel_begin(ls);
2,220,075✔
2123
  expr_unop(ls, v);
2,220,069✔
2124
  op = token2binop(ls->tok);
2,211,538✔
2125
  while (op != OPR_NOBINOPR && priority[op].left > limit) {
2,740,861✔
2126
    ExpDesc v2;
529,833✔
2127
    BinOpr nextop;
529,833✔
2128
    lj_lex_next(ls);
529,833✔
2129
    bcemit_binop_left(ls->fs, op, v);
529,787✔
2130
    /* Parse binary expression with higher priority. */
2131
    nextop = expr_binop(ls, &v2, priority[op].right);
529,787✔
2132
    bcemit_binop(ls->fs, op, v, &v2);
529,323✔
2133
    op = nextop;
529,323✔
2134
  }
2135
  synlevel_end(ls);
2,211,028✔
2136
  return op;  /* Return unconsumed binary operator (if any). */
2,211,028✔
2137
}
2138

2139
/* Parse expression. */
2140
static void expr(LexState *ls, ExpDesc *v)
1,390,376✔
2141
{
2142
  expr_binop(ls, v, 0);  /* Priority 0: parse whole expression. */
1,281,932✔
2143
}
649,405✔
2144

2145
/* Assign expression to the next register. */
2146
static void expr_next(LexState *ls)
3,510✔
2147
{
2148
  ExpDesc e;
3,510✔
2149
  expr(ls, &e);
3,510✔
2150
  expr_tonextreg(ls->fs, &e);
3,510✔
2151
}
3,510✔
2152

2153
/* Parse conditional expression. */
2154
static BCPos expr_cond(LexState *ls)
104,934✔
2155
{
2156
  ExpDesc v;
104,934✔
2157
  expr(ls, &v);
104,934✔
2158
  if (v.k == VKNIL) v.k = VKFALSE;
104,928✔
2159
  bcemit_branch_t(ls->fs, &v);
104,928✔
2160
  return v.f;
104,928✔
2161
}
2162

2163
/* -- Assignments --------------------------------------------------------- */
2164

2165
/* List of LHS variables. */
2166
typedef struct LHSVarList {
2167
  ExpDesc v;                        /* LHS variable. */
2168
  struct LHSVarList *prev;        /* Link to previous LHS variable. */
2169
} LHSVarList;
2170

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

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

2219
/* Recursively parse assignment statement. */
2220
static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars)
400,299✔
2221
{
2222
  ExpDesc e;
400,299✔
2223
  checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX);
400,299✔
2224
  if (lex_opt(ls, ',')) {  /* Collect LHS list and recurse upwards. */
400,033✔
2225
    LHSVarList vl;
653✔
2226
    vl.prev = lh;
653✔
2227
    expr_primary(ls, &vl.v);
653✔
2228
    if (vl.v.k == VLOCAL)
652✔
2229
      assign_hazard(ls, lh, &vl.v);
435✔
2230
    checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names");
652✔
2231
    parse_assignment(ls, &vl, nvars+1);
652✔
2232
  } else {  /* Parse RHS. */
2233
    BCReg nexps;
399,380✔
2234
    lex_check(ls, '=');
399,380✔
2235
    nexps = expr_list(ls, &e);
395,835✔
2236
    if (nexps == nvars) {
394,390✔
2237
      if (e.k == VCALL) {
394,171✔
2238
        if (bc_op(*bcptr(ls->fs, &e)) == BC_VARG) {  /* Vararg assignment. */
4,802✔
2239
          ls->fs->freereg--;
14✔
2240
          e.k = VRELOCABLE;
14✔
2241
        } else {  /* Multiple call results. */
2242
          e.u.s.info = e.u.s.aux;  /* Base of call is not relocatable. */
4,788✔
2243
          e.k = VNONRELOC;
4,788✔
2244
        }
2245
      }
2246
      bcemit_store(ls->fs, &lh->v, &e);
394,171✔
2247
      return;
394,171✔
2248
    }
2249
    assign_adjust(ls, nvars, nexps, &e);
219✔
2250
  }
2251
  /* Assign RHS to LHS and recurse downwards. */
2252
  expr_init(&e, VNONRELOC, ls->fs->freereg-1);
746✔
2253
  bcemit_store(ls->fs, &lh->v, &e);
746✔
2254
}
2255

2256
/* Parse call statement or assignment. */
2257
static void parse_call_assign(LexState *ls)
437,035✔
2258
{
2259
  FuncState *fs = ls->fs;
437,035✔
2260
  LHSVarList vl;
437,035✔
2261
  expr_primary(ls, &vl.v);
437,035✔
2262
  if (vl.v.k == VCALL) {  /* Function call statement. */
433,050✔
2263
    setbc_b(bcptr(fs, &vl.v), 1);  /* No results. */
33,403✔
2264
  } else {  /* Start of an assignment. */
2265
    vl.prev = NULL;
399,647✔
2266
    parse_assignment(ls, &vl, 1);
399,647✔
2267
  }
2268
}
427,793✔
2269

2270
/* Parse 'local' statement. */
2271
static void parse_local(LexState *ls)
63,124✔
2272
{
2273
  if (lex_opt(ls, TK_function)) {  /* Local function declaration. */
63,124✔
2274
    ExpDesc v, b;
3,883✔
2275
    FuncState *fs = ls->fs;
3,883✔
2276
    var_new(ls, 0, lex_str(ls));
3,883✔
2277
    expr_init(&v, VLOCAL, fs->freereg);
3,883✔
2278
    v.u.s.aux = fs->varmap[fs->freereg];
3,883✔
2279
    bcreg_reserve(fs, 1);
3,883✔
2280
    var_add(ls, 1);
3,883✔
2281
    parse_body(ls, &b, 0, ls->linenumber);
3,883✔
2282
    /* bcemit_store(fs, &v, &b) without setting VSTACK_VAR_RW. */
2283
    expr_free(fs, &b);
3,883✔
2284
    expr_toreg(fs, &b, v.u.s.info);
3,883✔
2285
    /* The upvalue is in scope, but the local is only valid after the store. */
2286
    var_get(ls, fs, fs->nactvar - 1).startpc = fs->pc;
3,883✔
2287
  } else {  /* Local variable declaration. */
2288
    ExpDesc e;
2289
    BCReg nexps, nvars = 0;
2290
    do {  /* Collect LHS. */
61,527✔
2291
      var_new(ls, nvars++, lex_str(ls));
61,527✔
2292
    } while (lex_opt(ls, ','));
61,514✔
2293
    if (lex_opt(ls, '=')) {  /* Optional RHS. */
59,228✔
2294
      nexps = expr_list(ls, &e);
42,197✔
2295
    } else {  /* Or implicitly set to nil. */
2296
      e.k = VVOID;
17,028✔
2297
      nexps = 0;
17,028✔
2298
    }
2299
    assign_adjust(ls, nvars, nexps, &e);
59,152✔
2300
    var_add(ls, nvars);
118,304✔
2301
  }
2302
}
63,035✔
2303

2304
/* Parse 'function' statement. */
2305
static void parse_func(LexState *ls, BCLine line)
8,534✔
2306
{
2307
  FuncState *fs;
8,534✔
2308
  ExpDesc v, b;
8,534✔
2309
  int needself = 0;
8,534✔
2310
  lj_lex_next(ls);  /* Skip 'function'. */
8,534✔
2311
  /* Parse function name. */
2312
  var_lookup(ls, &v);
8,534✔
2313
  while (ls->tok == '.')  /* Multiple dot-separated fields. */
8,591✔
2314
    expr_field(ls, &v);
265✔
2315
  if (ls->tok == ':') {  /* Optional colon to signify method call. */
8,326✔
2316
    needself = 1;
31✔
2317
    expr_field(ls, &v);
31✔
2318
  }
2319
  parse_body(ls, &b, needself, line);
8,326✔
2320
  fs = ls->fs;
6,794✔
2321
  bcemit_store(fs, &v, &b);
6,794✔
2322
  fs->bcbase[fs->pc - 1].line = line;  /* Set line for the store. */
6,794✔
2323
}
6,794✔
2324

2325
/* -- Control transfer statements ----------------------------------------- */
2326

2327
/* Check for end of block. */
2328
static int parse_isend(LexToken tok)
844,265✔
2329
{
2330
  switch (tok) {
844,265✔
2331
  case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof:
2332
    return 1;
2333
  default:
2334
    return 0;
725,918✔
2335
  }
2336
}
2337

2338
/* Parse 'return' statement. */
2339
static void parse_return(LexState *ls)
30,193✔
2340
{
2341
  BCIns ins;
30,193✔
2342
  FuncState *fs = ls->fs;
30,193✔
2343
  lj_lex_next(ls);  /* Skip 'return'. */
30,193✔
2344
  fs->flags |= PROTO_HAS_RETURN;
30,192✔
2345
  if (parse_isend(ls->tok) || ls->tok == ';') {  /* Bare return. */
30,192✔
2346
    ins = BCINS_AD(BC_RET0, 0, 1);
2347
  } else {  /* Return with one or more values. */
2348
    ExpDesc e;  /* Receives the _last_ expression in the list. */
29,908✔
2349
    BCReg nret = expr_list(ls, &e);
29,908✔
2350
    if (nret == 1) {  /* Return one result. */
25,739✔
2351
      if (e.k == VCALL) {  /* Check for tail call. */
25,585✔
2352
        BCIns *ip = bcptr(fs, &e);
3,196✔
2353
        /* It doesn't pay off to add BC_VARGT just for 'return ...'. */
2354
        if (bc_op(*ip) == BC_VARG) goto notailcall;
3,196✔
2355
        fs->pc--;
3,194✔
2356
        ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip));
3,194✔
2357
      } else {  /* Can return the result from any register. */
2358
        ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2);
22,389✔
2359
      }
2360
    } else {
2361
      if (e.k == VCALL) {  /* Append all results from a call. */
154✔
2362
      notailcall:
27✔
2363
        setbc_b(bcptr(fs, &e), 0);
29✔
2364
        ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar);
29✔
2365
      } else {
2366
        expr_tonextreg(fs, &e);  /* Force contiguous registers. */
127✔
2367
        ins = BCINS_AD(BC_RET, fs->nactvar, nret+1);
127✔
2368
      }
2369
    }
2370
  }
2371
  if (fs->flags & PROTO_CHILD)
26,023✔
2372
    bcemit_AJ(fs, BC_UCLO, 0, 0);  /* May need to close upvalues first. */
759✔
2373
  bcemit_INS(fs, ins);
26,023✔
2374
}
26,023✔
2375

2376
/* Parse 'break' statement. */
2377
static void parse_break(LexState *ls)
49,384✔
2378
{
2379
  ls->fs->bl->flags |= FSCOPE_BREAK;
49,384✔
2380
  gola_new(ls, NAME_BREAK, VSTACK_GOTO, bcemit_jmp(ls->fs));
49,384✔
2381
}
49,384✔
2382

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

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

2427
/* -- Blocks, loops and conditional statements ---------------------------- */
2428

2429
/* Parse a block. */
2430
static void parse_block(LexState *ls)
126,015✔
2431
{
2432
  FuncState *fs = ls->fs;
126,015✔
2433
  FuncScope bl;
126,015✔
2434
  fscope_begin(fs, &bl, 0);
126,015✔
2435
  parse_chunk(ls);
126,015✔
2436
  fscope_end(fs);
125,273✔
2437
}
125,273✔
2438

2439
/* Parse 'while' statement. */
2440
static void parse_while(LexState *ls, BCLine line)
33,233✔
2441
{
2442
  FuncState *fs = ls->fs;
33,233✔
2443
  BCPos start, loop, condexit;
33,233✔
2444
  FuncScope bl;
33,233✔
2445
  lj_lex_next(ls);  /* Skip 'while'. */
33,233✔
2446
  start = fs->lasttarget = fs->pc;
33,233✔
2447
  condexit = expr_cond(ls);
33,233✔
2448
  fscope_begin(fs, &bl, FSCOPE_LOOP);
33,232✔
2449
  lex_check(ls, TK_do);
33,232✔
2450
  loop = bcemit_AD(fs, BC_LOOP, fs->nactvar, 0);
33,231✔
2451
  parse_block(ls);
33,231✔
2452
  jmp_patch(fs, bcemit_jmp(fs), start);
33,032✔
2453
  lex_match(ls, TK_end, TK_while, line);
33,032✔
2454
  fscope_end(fs);
33,030✔
2455
  jmp_tohere(fs, condexit);
33,030✔
2456
  jmp_patchins(fs, loop, fs->pc);
33,030✔
2457
}
33,030✔
2458

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

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

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

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

2599
/* Parse 'for' statement. */
2600
static void parse_for(LexState *ls, BCLine line)
2,512✔
2601
{
2602
  FuncState *fs = ls->fs;
2,512✔
2603
  GCstr *varname;
2,512✔
2604
  FuncScope bl;
2,512✔
2605
  fscope_begin(fs, &bl, FSCOPE_LOOP);
2,512✔
2606
  lj_lex_next(ls);  /* Skip 'for'. */
2,512✔
2607
  varname = lex_str(ls);  /* Get first variable name. */
2,512✔
2608
  if (ls->tok == '=')
2,512✔
2609
    parse_for_num(ls, varname, line);
1,715✔
2610
  else if (ls->tok == ',' || ls->tok == TK_in)
797✔
2611
    parse_for_iter(ls, varname);
796✔
2612
  else
2613
    err_syntax(ls, LJ_ERR_XFOR);
1✔
2614
  lex_match(ls, TK_end, TK_for, line);
2,510✔
2615
  fscope_end(fs);  /* Resolve break list. */
2,509✔
2616
}
2,509✔
2617

2618
/* Parse condition and 'then' block. */
2619
static BCPos parse_then(LexState *ls)
55,269✔
2620
{
2621
  BCPos condexit;
55,269✔
2622
  lj_lex_next(ls);  /* Skip 'if' or 'elseif'. */
55,269✔
2623
  condexit = expr_cond(ls);
55,269✔
2624
  lex_check(ls, TK_then);
55,264✔
2625
  parse_block(ls);
55,259✔
2626
  return condexit;
55,257✔
2627
}
2628

2629
/* Parse 'if' statement. */
2630
static void parse_if(LexState *ls, BCLine line)
54,762✔
2631
{
2632
  FuncState *fs = ls->fs;
54,762✔
2633
  BCPos flist;
54,762✔
2634
  BCPos escapelist = NO_JMP;
54,762✔
2635
  flist = parse_then(ls);
54,762✔
2636
  while (ls->tok == TK_elseif) {  /* Parse multiple 'elseif' blocks. */
55,269✔
2637
    jmp_append(fs, &escapelist, bcemit_jmp(fs));
507✔
2638
    jmp_tohere(fs, flist);
507✔
2639
    flist = parse_then(ls);
507✔
2640
  }
2641
  if (ls->tok == TK_else) {  /* Parse optional 'else' block. */
54,750✔
2642
    jmp_append(fs, &escapelist, bcemit_jmp(fs));
34,271✔
2643
    jmp_tohere(fs, flist);
34,271✔
2644
    lj_lex_next(ls);  /* Skip 'else'. */
34,271✔
2645
    parse_block(ls);
34,271✔
2646
  } else {
2647
    jmp_append(fs, &escapelist, flist);
20,479✔
2648
  }
2649
  jmp_tohere(fs, escapelist);
54,552✔
2650
  lex_match(ls, TK_end, TK_if, line);
54,552✔
2651
}
54,534✔
2652

2653
/* -- Parse statements ---------------------------------------------------- */
2654

2655
/* Parse a statement. Returns 1 if it must be the last one in a chunk. */
2656
static int parse_stmt(LexState *ls)
696,007✔
2657
{
2658
  BCLine line = ls->linenumber;
696,007✔
2659
  switch (ls->tok) {
696,007✔
2660
  case TK_if:
54,762✔
2661
    parse_if(ls, line);
54,762✔
2662
    break;
54,762✔
2663
  case TK_while:
33,233✔
2664
    parse_while(ls, line);
33,233✔
2665
    break;
33,233✔
2666
  case TK_do:
744✔
2667
    lj_lex_next(ls);
744✔
2668
    parse_block(ls);
744✔
2669
    lex_match(ls, TK_end, TK_do, line);
401✔
2670
    break;
401✔
2671
  case TK_for:
2,512✔
2672
    parse_for(ls, line);
2,512✔
2673
    break;
2,512✔
2674
  case TK_repeat:
16,434✔
2675
    parse_repeat(ls, line);
16,434✔
2676
    break;
16,434✔
2677
  case TK_function:
8,534✔
2678
    parse_func(ls, line);
8,534✔
2679
    break;
8,534✔
2680
  case TK_local:
63,124✔
2681
    lj_lex_next(ls);
63,124✔
2682
    parse_local(ls);
63,124✔
2683
    break;
63,124✔
2684
  case TK_return:
30,193✔
2685
    parse_return(ls);
30,193✔
2686
    return 1;  /* Must be last. */
30,193✔
2687
  case TK_break:
49,380✔
2688
    lj_lex_next(ls);
49,380✔
2689
    parse_break(ls);
49,380✔
2690
    return !LJ_52;  /* Must be last in Lua 5.1. */
49,380✔
2691
#if LJ_52
2692
  case ';':
2693
    lj_lex_next(ls);
2694
    break;
2695
#endif
2696
  case TK_label:
31✔
2697
    parse_label(ls);
31✔
2698
    break;
31✔
2699
  case TK_goto:
26✔
2700
    if (LJ_52 || lj_lex_lookahead(ls) == TK_name) {
26✔
2701
      lj_lex_next(ls);
25✔
2702
      parse_goto(ls);
25✔
2703
      break;
25✔
2704
    }
2705
    /* fallthrough */
2706
  default:
2707
    parse_call_assign(ls);
437,035✔
2708
    break;
437,035✔
2709
  }
2710
  return 0;
2711
}
2712

2713
/* A chunk is a list of statements optionally separated by semicolons. */
2714
static void parse_chunk(LexState *ls)
209,479✔
2715
{
2716
  int islast = 0;
209,479✔
2717
  synlevel_begin(ls);
209,479✔
2718
  while (!islast && !parse_isend(ls->tok)) {
889,446✔
2719
    islast = parse_stmt(ls);
696,007✔
2720
    lex_opt(ls, ';');
679,969✔
2721
    lj_assertLS(ls->fs->framesize >= ls->fs->freereg &&
679,969✔
2722
                ls->fs->freereg >= ls->fs->nactvar,
2723
                "bad regalloc");
2724
    ls->fs->freereg = ls->fs->nactvar;  /* Free registers after each stmt. */
679,969✔
2725
  }
2726
  synlevel_end(ls);
193,439✔
2727
}
193,439✔
2728

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

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