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

tarantool / luajit / 11380194690

17 Oct 2024 07:17AM UTC coverage: 92.918% (-0.06%) from 92.974%
11380194690

push

github

Buristan
Limit CSE for IR_CARG to fix loop optimizations.

Thanks to Peter Cawley.

(cherry picked from commit 3bdc6498c)

`IR_CALLXS` for the vararg function contains `IR_CARG(fptr, ctid)` as
the second operand. The `loop_emit_phi()` scans only the first operand
of the IR, so the second is not marked as PHI. In this case, when the IR
appears in both the invariant and variant parts of the loop, CSE may
remove it and thus lead to incorrect emitting results.

This patch tweaks the CSE rules to avoid CSE across the `IR_LOOP`.

Sergey Kaplun:
* added the description and the test for the problem

Part of tarantool/tarantool#10199

5692 of 6033 branches covered (94.35%)

Branch coverage included in aggregate %.

4 of 4 new or added lines in 1 file covered. (100.0%)

21 existing lines in 5 files now uncovered.

21702 of 23449 relevant lines covered (92.55%)

2969960.86 hits per line

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

91.98
/src/luajit.c
1
/*
2
** LuaJIT frontend. Runs commands, scripts, read-eval-print (REPL) etc.
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
#include <stdio.h>
10
#include <stdlib.h>
11
#include <string.h>
12

13
#define luajit_c
14

15
#include "lua.h"
16
#include "lauxlib.h"
17
#include "lualib.h"
18
#include "luajit.h"
19

20
#include "lj_arch.h"
21

22
#if LJ_TARGET_POSIX
23
#include <unistd.h>
24
#define lua_stdin_is_tty()        isatty(0)
25
#elif LJ_TARGET_WINDOWS
26
#include <io.h>
27
#ifdef __BORLANDC__
28
#define lua_stdin_is_tty()        isatty(_fileno(stdin))
29
#else
30
#define lua_stdin_is_tty()        _isatty(_fileno(stdin))
31
#endif
32
#else
33
#define lua_stdin_is_tty()        1
34
#endif
35

36
#if !LJ_TARGET_CONSOLE
37
#include <signal.h>
38
#endif
39

40
static lua_State *globalL = NULL;
41
static const char *progname = LUA_PROGNAME;
42

43
#if !LJ_TARGET_CONSOLE
44
static void lstop(lua_State *L, lua_Debug *ar)
×
45
{
46
  (void)ar;  /* unused arg. */
×
47
  lua_sethook(L, NULL, 0, 0);
×
48
  /* Avoid luaL_error -- a C hook doesn't add an extra frame. */
49
  luaL_where(L, 0);
×
50
  lua_pushfstring(L, "%sinterrupted!", lua_tostring(L, -1));
×
51
  lua_error(L);
×
52
}
×
53

54
static void laction(int i)
×
55
{
56
  signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
×
57
                         terminate process (default action) */
58
  lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
×
59
}
×
60
#endif
61

62
static void print_usage(void)
5✔
63
{
64
  fputs("usage: ", stderr);
5✔
65
  fputs(progname, stderr);
5✔
66
  fputs(" [options]... [script [args]...].\n"
5✔
67
  "Available options are:\n"
68
  "  -e chunk  Execute string " LUA_QL("chunk") ".\n"
69
  "  -l name   Require library " LUA_QL("name") ".\n"
70
  "  -b ...    Save or list bytecode.\n"
71
  "  -j cmd    Perform LuaJIT control command.\n"
72
  "  -O[opt]   Control LuaJIT optimizations.\n"
73
  "  -i        Enter interactive mode after executing " LUA_QL("script") ".\n"
74
  "  -v        Show version information.\n"
75
  "  -t<cmd>   Execute tool.\n"
76
  "  -E        Ignore environment variables.\n"
77
  "  --        Stop handling options.\n"
78
  "  -         Execute stdin and stop handling options.\n", stderr);
79
  fflush(stderr);
5✔
80
}
5✔
81

82
static void print_tools_usage(void)
2✔
83
{
84
  fputs("usage: ", stderr);
2✔
85
  fputs(progname, stderr);
2✔
86
  fputs(" -t<cmd>\n"
2✔
87
  "Available tools are:\n"
88
  "  -m [--leak-only] input  Memprof profile data parser.\n"
89
  "  -s input                Sysprof profile data parser.\n", stderr);
90
  fflush(stderr);
2✔
91
}
2✔
92

93
static void l_message(const char *pname, const char *msg)
7✔
94
{
95
  if (pname) { fputs(pname, stderr); fputc(':', stderr); fputc(' ', stderr); }
7✔
96
  fputs(msg, stderr); fputc('\n', stderr);
7✔
97
  fflush(stderr);
7✔
98
}
7✔
99

100
static int report(lua_State *L, int status)
636✔
101
{
102
  if (status && !lua_isnil(L, -1)) {
636✔
103
    const char *msg = lua_tostring(L, -1);
6✔
104
    if (msg == NULL) msg = "(error object is not a string)";
6✔
105
    l_message(progname, msg);
6✔
106
    lua_pop(L, 1);
6✔
107
  }
108
  return status;
636✔
109
}
110

111
static int traceback(lua_State *L)
4✔
112
{
113
  if (!lua_isstring(L, 1)) { /* Non-string error object? Try metamethod. */
4✔
114
    if (lua_isnoneornil(L, 1) ||
2✔
115
        !luaL_callmeta(L, 1, "__tostring") ||
1✔
UNCOV
116
        !lua_isstring(L, -1))
×
117
      return 1;  /* Return non-string error object. */
1✔
UNCOV
118
    lua_remove(L, 1);  /* Replace object by result of __tostring metamethod. */
×
119
  }
120
  luaL_traceback(L, L, lua_tostring(L, 1), 1);
3✔
121
  return 1;
3✔
122
}
123

124
static int docall(lua_State *L, int narg, int clear)
643✔
125
{
126
  int status;
643✔
127
  int base = lua_gettop(L) - narg;  /* function index */
643✔
128
  lua_pushcfunction(L, traceback);  /* push traceback function */
643✔
129
  lua_insert(L, base);  /* put it under chunk and args */
643✔
130
#if !LJ_TARGET_CONSOLE
131
  signal(SIGINT, laction);
643✔
132
#endif
133
  status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
933✔
134
#if !LJ_TARGET_CONSOLE
135
  signal(SIGINT, SIG_DFL);
461✔
136
#endif
137
  lua_remove(L, base);  /* remove traceback function */
461✔
138
  /* force a complete garbage collection in case of errors */
139
  if (status != LUA_OK) lua_gc(L, LUA_GCCOLLECT, 0);
461✔
140
  return status;
461✔
141
}
142

143
static void print_version(void)
9✔
144
{
145
  fputs(LUAJIT_VERSION " -- " LUAJIT_COPYRIGHT ". " LUAJIT_URL "\n", stdout);
9✔
146
}
9✔
147

148
static void print_jit_status(lua_State *L)
5✔
149
{
150
  int n;
5✔
151
  const char *s;
5✔
152
  lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
5✔
153
  lua_getfield(L, -1, "jit");  /* Get jit.* module table. */
5✔
154
  lua_remove(L, -2);
5✔
155
  lua_getfield(L, -1, "status");
5✔
156
  lua_remove(L, -2);
5✔
157
  n = lua_gettop(L);
5✔
158
  lua_call(L, 0, LUA_MULTRET);
5✔
159
  fputs(lua_toboolean(L, n) ? "JIT: ON" : "JIT: OFF", stdout);
5✔
160
  for (n++; (s = lua_tostring(L, n)); n++) {
75✔
161
    putc(' ', stdout);
70✔
162
    fputs(s, stdout);
70✔
163
  }
164
  putc('\n', stdout);
5✔
165
  lua_settop(L, 0);  /* clear stack */
5✔
166
}
5✔
167

168
static void createargtable(lua_State *L, char **argv, int argc, int argf)
341✔
169
{
170
  int i;
341✔
171
  lua_createtable(L, argc - argf, argf);
341✔
172
  for (i = 0; i < argc; i++) {
2,181✔
173
    lua_pushstring(L, argv[i]);
1,499✔
174
    lua_rawseti(L, -2, i - argf);
1,499✔
175
  }
176
  lua_setglobal(L, "arg");
341✔
177
}
341✔
178

179
static int dofile(lua_State *L, const char *name)
1✔
180
{
181
  int status = luaL_loadfile(L, name) || docall(L, 0, 1);
1✔
182
  return report(L, status);
1✔
183
}
184

185
static int dostring(lua_State *L, const char *s, const char *name)
297✔
186
{
187
  int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
297✔
188
  return report(L, status);
294✔
189
}
190

191
static int dolibrary(lua_State *L, const char *name)
57✔
192
{
193
  lua_getglobal(L, "require");
57✔
194
  lua_pushstring(L, name);
57✔
195
  return report(L, docall(L, 1, 1));
57✔
196
}
197

198
static void write_prompt(lua_State *L, int firstline)
133✔
199
{
200
  const char *p;
133✔
201
  lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
242✔
202
  p = lua_tostring(L, -1);
133✔
203
  if (p == NULL) p = firstline ? LUA_PROMPT : LUA_PROMPT2;
133✔
204
  fputs(p, stdout);
133✔
205
  fflush(stdout);
133✔
206
  lua_pop(L, 1);  /* remove global */
133✔
207
}
133✔
208

209
static int incomplete(lua_State *L, int status)
128✔
210
{
211
  if (status == LUA_ERRSYNTAX) {
128✔
212
    size_t lmsg;
109✔
213
    const char *msg = lua_tolstring(L, -1, &lmsg);
109✔
214
    const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
109✔
215
    if (strstr(msg, LUA_QL("<eof>")) == tp) {
109✔
216
      lua_pop(L, 1);
109✔
217
      return 1;
109✔
218
    }
219
  }
220
  return 0;  /* else... */
221
}
222

223
static int pushline(lua_State *L, int firstline)
133✔
224
{
225
  char buf[LUA_MAXINPUT];
133✔
226
  write_prompt(L, firstline);
133✔
227
  if (fgets(buf, LUA_MAXINPUT, stdin)) {
133✔
228
    size_t len = strlen(buf);
128✔
229
    if (len > 0 && buf[len-1] == '\n')
128✔
230
      buf[len-1] = '\0';
126✔
231
    if (firstline && buf[0] == '=')
128✔
232
      lua_pushfstring(L, "return %s", buf+1);
5✔
233
    else
234
      lua_pushstring(L, buf);
123✔
235
    return 1;
128✔
236
  }
237
  return 0;
238
}
239

240
static int loadline(lua_State *L)
24✔
241
{
242
  int status;
24✔
243
  lua_settop(L, 0);
24✔
244
  if (!pushline(L, 1))
24✔
245
    return -1;  /* no input */
246
  for (;;) {  /* repeat until gets a complete line */
237✔
247
    status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
128✔
248
    if (!incomplete(L, status)) break;  /* cannot try to add lines? */
128✔
249
    if (!pushline(L, 0))  /* no more input? */
109✔
250
      return -1;
251
    lua_pushliteral(L, "\n");  /* add a new line... */
109✔
252
    lua_insert(L, -2);  /* ...between the two lines */
109✔
253
    lua_concat(L, 3);  /* join them */
109✔
254
  }
255
  lua_remove(L, 1);  /* remove line */
19✔
256
  return status;
19✔
257
}
258

259
static void dotty(lua_State *L)
5✔
260
{
261
  int status;
5✔
262
  const char *oldprogname = progname;
5✔
263
  progname = NULL;
5✔
264
  while ((status = loadline(L)) != -1) {
29✔
265
    if (status == LUA_OK) status = docall(L, 0, 0);
19✔
266
    report(L, status);
19✔
267
    if (status == LUA_OK && lua_gettop(L) > 0) {  /* any result to print? */
19✔
268
      lua_getglobal(L, "print");
5✔
269
      lua_insert(L, 1);
5✔
270
      if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
5✔
271
        l_message(progname,
×
272
          lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)",
273
                              lua_tostring(L, -1)));
274
    }
275
  }
276
  lua_settop(L, 0);  /* clear stack */
5✔
277
  fputs("\n", stdout);
5✔
278
  fflush(stdout);
5✔
279
  progname = oldprogname;
5✔
280
}
5✔
281

282
static int handle_script(lua_State *L, char **argx)
272✔
283
{
284
  int status;
272✔
285
  const char *fname = argx[0];
272✔
286
  if (strcmp(fname, "-") == 0 && strcmp(argx[-1], "--") != 0)
272✔
287
    fname = NULL;  /* stdin */
4✔
288
  status = luaL_loadfile(L, fname);
272✔
289
  if (status == LUA_OK) {
272✔
290
    /* Fetch args from arg table. LUA_INIT or -e might have changed them. */
291
    int narg = 0;
271✔
292
    lua_getglobal(L, "arg");
271✔
293
    if (lua_istable(L, -1)) {
271✔
294
      do {
330✔
295
        narg++;
330✔
296
        lua_rawgeti(L, -narg, narg);
330✔
297
      } while (!lua_isnil(L, -1));
330✔
298
      lua_pop(L, 1);
271✔
299
      lua_remove(L, -narg);
271✔
300
      narg--;
271✔
301
    } else {
302
      lua_pop(L, 1);
×
303
    }
304
    status = docall(L, narg, 0);
271✔
305
  }
306
  return report(L, status);
93✔
307
}
308

309
/* Load add-on module. */
310
static int loadjitmodule(lua_State *L)
17✔
311
{
312
  lua_getglobal(L, "require");
17✔
313
  lua_pushliteral(L, "jit.");
17✔
314
  lua_pushvalue(L, -3);
17✔
315
  lua_concat(L, 2);
17✔
316
  if (lua_pcall(L, 1, 1, 0)) {
17✔
317
    const char *msg = lua_tostring(L, -1);
1✔
318
    if (msg && !strncmp(msg, "module ", 7))
1✔
319
      goto nomodule;
1✔
320
    return report(L, 1);
×
321
  }
322
  lua_getfield(L, -1, "start");
16✔
323
  if (lua_isnil(L, -1)) {
16✔
324
  nomodule:
×
325
    l_message(progname,
1✔
326
              "unknown luaJIT command or jit.* modules not installed");
327
    return 1;
1✔
328
  }
329
  lua_remove(L, -2);  /* Drop module table. */
16✔
330
  return 0;
16✔
331
}
332

333
/* Run command with options. */
334
static int runcmdopt(lua_State *L, const char *opt)
10✔
335
{
336
  int narg = 0;
10✔
337
  if (opt && *opt) {
10✔
338
    for (;;) {  /* Split arguments. */
10✔
339
      const char *p = strchr(opt, ',');
8✔
340
      narg++;
8✔
341
      if (!p) break;
8✔
342
      if (p == opt)
2✔
343
        lua_pushnil(L);
×
344
      else
345
        lua_pushlstring(L, opt, (size_t)(p - opt));
2✔
346
      opt = p + 1;
2✔
347
    }
348
    if (*opt)
6✔
349
      lua_pushstring(L, opt);
6✔
350
    else
351
      lua_pushnil(L);
×
352
  }
353
  return report(L, lua_pcall(L, narg, 0, 0));
10✔
354
}
355

356
/* JIT engine control command: try jit library first or load add-on module. */
357
static int dojitcmd(lua_State *L, const char *cmd)
4✔
358
{
359
  const char *opt = strchr(cmd, '=');
4✔
360
  lua_pushlstring(L, cmd, opt ? (size_t)(opt - cmd) : strlen(cmd));
4✔
361
  lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
4✔
362
  lua_getfield(L, -1, "jit");  /* Get jit.* module table. */
4✔
363
  lua_remove(L, -2);
4✔
364
  lua_pushvalue(L, -2);
4✔
365
  lua_gettable(L, -2);  /* Lookup library function. */
4✔
366
  if (!lua_isfunction(L, -1)) {
4✔
367
    lua_pop(L, 2);  /* Drop non-function and jit.* table, keep module name. */
1✔
368
    if (loadjitmodule(L))
1✔
369
      return 1;
370
  } else {
371
    lua_remove(L, -2);  /* Drop jit.* table. */
3✔
372
  }
373
  lua_remove(L, -2);  /* Drop module name. */
3✔
374
  return runcmdopt(L, opt ? opt+1 : opt);
3✔
375
}
376

377
static int runtoolcmd(lua_State *L, const char *tool_name)
18✔
378
{
379
  lua_getglobal(L, "require");
18✔
380
  lua_pushstring(L, tool_name);
18✔
381
  if (lua_pcall(L, 1, 1, 0)) {
18✔
382
    const char *msg = lua_tostring(L, -1);
×
383
    if (msg) {
×
384
      if (!strncmp(msg, "module ", 7))
×
385
        msg = "unknown luaJIT command or tools not installed";
×
386
      l_message(progname, msg);
×
387
    }
388
    return 1;
×
389
  }
390
  lua_getglobal(L, "arg");
18✔
391
  return report(L, lua_pcall(L, 1, 1, 0));
18✔
392
}
393

394
static int dotoolcmd(lua_State *L, const char *cmd)
395
{
396
  switch (cmd[0]) {
397
  case 'm':
398
    return runtoolcmd(L, "memprof");
399
  case 's':
400
    return runtoolcmd(L, "sysprof");
401
  default:
402
    print_tools_usage();
403
    break;
404
  }
405
  return -1;
406
}
407

408
/* Optimization flags. */
409
static int dojitopt(lua_State *L, const char *opt)
7✔
410
{
411
  lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
7✔
412
  lua_getfield(L, -1, "jit.opt");  /* Get jit.opt.* module table. */
7✔
413
  lua_remove(L, -2);
7✔
414
  lua_getfield(L, -1, "start");
7✔
415
  lua_remove(L, -2);
7✔
416
  return runcmdopt(L, opt);
7✔
417
}
418

419
/* Save or list bytecode. */
420
static int dobytecode(lua_State *L, char **argv)
16✔
421
{
422
  int narg = 0;
16✔
423
  lua_pushliteral(L, "bcsave");
16✔
424
  if (loadjitmodule(L))
16✔
425
    return 1;
426
  if (argv[0][2]) {
16✔
427
    narg++;
4✔
428
    argv[0][1] = '-';
4✔
429
    lua_pushstring(L, argv[0]+1);
4✔
430
  }
431
  for (argv++; *argv != NULL; narg++, argv++)
57✔
432
    lua_pushstring(L, *argv);
41✔
433
  report(L, lua_pcall(L, narg, 0, 0));
16✔
434
  return -1;
16✔
435
}
436

437
/* check that argument has no extra characters at the end */
438
#define notail(x)        {if ((x)[2] != '\0') return -1;}
439

440
#define FLAGS_INTERACTIVE        1
441
#define FLAGS_VERSION                2
442
#define FLAGS_EXEC                4
443
#define FLAGS_OPTION                8
444
#define FLAGS_NOENV                16
445
#define FLAGS_TOOL                32
446

447
static int collectargs(char **argv, int *flags)
346✔
448
{
449
  int i;
346✔
450
  for (i = 1; argv[i] != NULL; i++) {
721✔
451
    if (argv[i][0] != '-')  /* Not an option? */
691✔
452
      return i;
269✔
453
    switch (argv[i][1]) {  /* Check option. */
422✔
454
    case '-':
3✔
455
      notail(argv[i]);
3✔
456
      return i+1;
2✔
457
    case '\0':
458
      return i;
459
    case 'i':
5✔
460
      notail(argv[i]);
5✔
461
      *flags |= FLAGS_INTERACTIVE;
5✔
462
      /* fallthrough */
463
    case 'v':
9✔
464
      notail(argv[i]);
9✔
465
      *flags |= FLAGS_VERSION;
9✔
466
      break;
9✔
467
    case 't':
20✔
468
      *flags |= FLAGS_TOOL;
20✔
469
      return i + 1;
20✔
470
    case 'e':
299✔
471
      *flags |= FLAGS_EXEC;
299✔
472
      /* fallthrough */
473
    case 'j':  /* LuaJIT extension */
360✔
474
    case 'l':
475
      *flags |= FLAGS_OPTION;
360✔
476
      if (argv[i][2] == '\0') {
360✔
477
        i++;
346✔
478
        if (argv[i] == NULL) return -1;
346✔
479
      }
480
      break;
481
    case 'O': break;  /* LuaJIT extension */
482
    case 'b':  /* LuaJIT extension */
16✔
483
      if (*flags) return -1;
16✔
484
      *flags |= FLAGS_EXEC;
16✔
485
      return i+1;
16✔
486
    case 'E':
1✔
487
      *flags |= FLAGS_NOENV;
1✔
488
      break;
1✔
489
    default: return -1;  /* invalid option */
490
    }
491
  }
492
  return i;
493
}
494

495
static int runargs(lua_State *L, char **argv, int argn)
341✔
496
{
497
  int i;
341✔
498
  for (i = 1; i < argn; i++) {
710✔
499
    if (argv[i] == NULL) continue;
413✔
500
    lua_assert(argv[i][0] == '-');
413✔
501
    switch (argv[i][1]) {
413✔
502
    case 'e': {
297✔
503
      const char *chunk = argv[i] + 2;
297✔
504
      if (*chunk == '\0') chunk = argv[++i];
297✔
505
      lua_assert(chunk != NULL);
297✔
506
      if (dostring(L, chunk, "=(command line)") != 0)
297✔
507
        return 1;
508
      break;
509
      }
510
    case 'l': {
57✔
511
      const char *filename = argv[i] + 2;
57✔
512
      if (*filename == '\0') filename = argv[++i];
57✔
513
      lua_assert(filename != NULL);
57✔
514
      if (dolibrary(L, filename))
57✔
515
        return 1;
516
      break;
517
      }
518
    case 'j': {  /* LuaJIT extension. */
4✔
519
      const char *cmd = argv[i] + 2;
4✔
520
      if (*cmd == '\0') cmd = argv[++i];
4✔
521
      lua_assert(cmd != NULL);
4✔
522
      if (dojitcmd(L, cmd))
4✔
523
        return 1;
524
      break;
525
      }
526
    case 't': { /* Tarantool's fork extension. */
20✔
527
      const char *cmd = argv[i] + 2;
20✔
528
      return dotoolcmd(L, cmd) != LUA_OK;
20✔
529
    }
530
    case 'O':  /* LuaJIT extension. */
7✔
531
      if (dojitopt(L, argv[i] + 2))
7✔
532
        return 1;
533
      break;
534
    case 'b':  /* LuaJIT extension. */
16✔
535
      return dobytecode(L, argv+i);
16✔
536
    default: break;
537
    }
538
  }
539
  return LUA_OK;
540
}
541

542
static int handle_luainit(lua_State *L)
340✔
543
{
544
#if LJ_TARGET_CONSOLE
545
  const char *init = NULL;
546
#else
547
  const char *init = getenv(LUA_INIT);
340✔
548
#endif
549
  if (init == NULL)
340✔
550
    return LUA_OK;
551
  else if (init[0] == '@')
×
552
    return dofile(L, init+1);
×
553
  else
554
    return dostring(L, init, "=" LUA_INIT);
×
555
}
556

557
static struct Smain {
558
  char **argv;
559
  int argc;
560
  int status;
561
} smain;
562

563
static int pmain(lua_State *L)
346✔
564
{
565
  struct Smain *s = &smain;
346✔
566
  char **argv = s->argv;
346✔
567
  int argn;
346✔
568
  int flags = 0;
346✔
569
  globalL = L;
346✔
570
  if (argv[0] && argv[0][0]) progname = argv[0];
346✔
571

572
  LUAJIT_VERSION_SYM();  /* Linker-enforced version check. */
346✔
573

574
  argn = collectargs(argv, &flags);
346✔
575
  if (argn < 0) {  /* Invalid args? */
346✔
576
    print_usage();
5✔
577
    s->status = 1;
5✔
578
    return 0;
5✔
579
  }
580

581
  if ((flags & FLAGS_NOENV)) {
341✔
582
    lua_pushboolean(L, 1);
1✔
583
    lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
1✔
584
  }
585

586
  /* Stop collector during library initialization. */
587
  lua_gc(L, LUA_GCSTOP, 0);
341✔
588
  luaL_openlibs(L);
341✔
589
  lua_gc(L, LUA_GCRESTART, -1);
341✔
590

591
  createargtable(L, argv, s->argc, (flags & FLAGS_TOOL) ? argn - 1 : argn);
341✔
592

593
  if (!(flags & FLAGS_NOENV)) {
341✔
594
    s->status = handle_luainit(L);
340✔
595
    if (s->status != LUA_OK) return 0;
340✔
596
  }
597

598
  if ((flags & FLAGS_VERSION)) print_version();
341✔
599

600
  s->status = runargs(L, argv, argn);
341✔
601
  if (s->status != LUA_OK) return 0;
320✔
602

603
  if (s->argc > argn) {
297✔
604
    s->status = handle_script(L, argv + argn);
272✔
605
    if (s->status != LUA_OK) return 0;
93✔
606
  }
607

608
  if ((flags & FLAGS_INTERACTIVE)) {
116✔
609
    print_jit_status(L);
5✔
610
    dotty(L);
5✔
611
  } else if (s->argc == argn && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) {
111✔
612
    if (lua_stdin_is_tty()) {
1✔
613
      print_version();
×
614
      print_jit_status(L);
×
615
      dotty(L);
×
616
    } else {
617
      dofile(L, NULL);  /* Executes stdin as a file. */
1✔
618
    }
619
  }
620
  return 0;
621
}
622

623
int main(int argc, char **argv)
346✔
624
{
625
  int status;
346✔
626
  lua_State *L = lua_open();
346✔
627
  if (L == NULL) {
346✔
628
    l_message(argv[0], "cannot create state: not enough memory");
×
629
    return EXIT_FAILURE;
×
630
  }
631
  smain.argc = argc;
346✔
632
  smain.argv = argv;
346✔
633
  status = lua_cpcall(L, pmain, NULL);
346✔
634
  report(L, status);
146✔
635
  lua_close(L);
146✔
636
  return (status || smain.status > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
146✔
637
}
638

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

© 2025 Coveralls, Inc