aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2016-07-17 16:23:49 +0200
committerMike Pall <mike>2016-07-17 16:23:49 +0200
commit92d9ff211ae864777a8580b5a7326d5f408161ce (patch)
tree894941850627260d7c54c86f406c54b1b370f415
parent7374046299678889202459f6c26fa78b3118eae9 (diff)
downloadluajit-92d9ff211ae864777a8580b5a7326d5f408161ce.tar.gz
luajit-92d9ff211ae864777a8580b5a7326d5f408161ce.tar.bz2
luajit-92d9ff211ae864777a8580b5a7326d5f408161ce.zip
Set arg table before evaluating LUA_INIT and -e chunks.
-rw-r--r--doc/extensions.html1
-rw-r--r--src/luajit.c103
2 files changed, 60 insertions, 44 deletions
diff --git a/doc/extensions.html b/doc/extensions.html
index 368b527c..9d666293 100644
--- a/doc/extensions.html
+++ b/doc/extensions.html
@@ -349,6 +349,7 @@ break the Lua/C API and ABI (e.g. <tt>_ENV</tt>).
349LuaJIT supports some extensions from Lua&nbsp;5.3: 349LuaJIT supports some extensions from Lua&nbsp;5.3:
350<ul> 350<ul>
351<li>Unicode escape <tt>'\u{XX...}'</tt> embeds the UTF-8 encoding in string literals.</li> 351<li>Unicode escape <tt>'\u{XX...}'</tt> embeds the UTF-8 encoding in string literals.</li>
352<li>The argument table <tt>arg</tt> can be read (and modified) by <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li>
352</ul> 353</ul>
353 354
354<h2 id="exceptions">C++ Exception Interoperability</h2> 355<h2 id="exceptions">C++ Exception Interoperability</h2>
diff --git a/src/luajit.c b/src/luajit.c
index 00e12bd3..4de2d43c 100644
--- a/src/luajit.c
+++ b/src/luajit.c
@@ -152,22 +152,15 @@ static void print_jit_status(lua_State *L)
152 putc('\n', stdout); 152 putc('\n', stdout);
153} 153}
154 154
155static int getargs(lua_State *L, char **argv, int n) 155static void createargtable(lua_State *L, char **argv, int argc, int argf)
156{ 156{
157 int narg;
158 int i; 157 int i;
159 int argc = 0; 158 lua_createtable(L, argc - argf, argf);
160 while (argv[argc]) argc++; /* count total number of arguments */
161 narg = argc - (n + 1); /* number of arguments to the script */
162 luaL_checkstack(L, narg + 3, "too many arguments to script");
163 for (i = n+1; i < argc; i++)
164 lua_pushstring(L, argv[i]);
165 lua_createtable(L, narg, n + 1);
166 for (i = 0; i < argc; i++) { 159 for (i = 0; i < argc; i++) {
167 lua_pushstring(L, argv[i]); 160 lua_pushstring(L, argv[i]);
168 lua_rawseti(L, -2, i - n); 161 lua_rawseti(L, -2, i - argf);
169 } 162 }
170 return narg; 163 lua_setglobal(L, "arg");
171} 164}
172 165
173static int dofile(lua_State *L, const char *name) 166static int dofile(lua_State *L, const char *name)
@@ -273,21 +266,30 @@ static void dotty(lua_State *L)
273 progname = oldprogname; 266 progname = oldprogname;
274} 267}
275 268
276static int handle_script(lua_State *L, char **argv, int n) 269static int handle_script(lua_State *L, char **argx)
277{ 270{
278 int status; 271 int status;
279 const char *fname; 272 const char *fname = argx[0];
280 int narg = getargs(L, argv, n); /* collect arguments */ 273 if (strcmp(fname, "-") == 0 && strcmp(argx[-1], "--") != 0)
281 lua_setglobal(L, "arg");
282 fname = argv[n];
283 if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
284 fname = NULL; /* stdin */ 274 fname = NULL; /* stdin */
285 status = luaL_loadfile(L, fname); 275 status = luaL_loadfile(L, fname);
286 lua_insert(L, -(narg+1)); 276 if (status == 0) {
287 if (status == 0) 277 /* Fetch args from arg table. LUA_INIT or -e might have changed them. */
278 int narg = 0;
279 lua_getglobal(L, "arg");
280 if (lua_istable(L, -1)) {
281 do {
282 narg++;
283 lua_rawgeti(L, -narg, narg);
284 } while (!lua_isnil(L, -1));
285 lua_pop(L, 1);
286 lua_remove(L, -narg);
287 narg--;
288 } else {
289 lua_pop(L, 1);
290 }
288 status = docall(L, narg, 0); 291 status = docall(L, narg, 0);
289 else 292 }
290 lua_pop(L, narg);
291 return report(L, status); 293 return report(L, status);
292} 294}
293 295
@@ -384,7 +386,8 @@ static int dobytecode(lua_State *L, char **argv)
384 } 386 }
385 for (argv++; *argv != NULL; narg++, argv++) 387 for (argv++; *argv != NULL; narg++, argv++)
386 lua_pushstring(L, *argv); 388 lua_pushstring(L, *argv);
387 return report(L, lua_pcall(L, narg, 0, 0)); 389 report(L, lua_pcall(L, narg, 0, 0));
390 return 1;
388} 391}
389 392
390/* check that argument has no extra characters at the end */ 393/* check that argument has no extra characters at the end */
@@ -405,7 +408,7 @@ static int collectargs(char **argv, int *flags)
405 switch (argv[i][1]) { /* Check option. */ 408 switch (argv[i][1]) { /* Check option. */
406 case '-': 409 case '-':
407 notail(argv[i]); 410 notail(argv[i]);
408 return (argv[i+1] != NULL ? i+1 : 0); 411 return i+1;
409 case '\0': 412 case '\0':
410 return i; 413 return i;
411 case 'i': 414 case 'i':
@@ -430,23 +433,23 @@ static int collectargs(char **argv, int *flags)
430 case 'b': /* LuaJIT extension */ 433 case 'b': /* LuaJIT extension */
431 if (*flags) return -1; 434 if (*flags) return -1;
432 *flags |= FLAGS_EXEC; 435 *flags |= FLAGS_EXEC;
433 return 0; 436 return i+1;
434 case 'E': 437 case 'E':
435 *flags |= FLAGS_NOENV; 438 *flags |= FLAGS_NOENV;
436 break; 439 break;
437 default: return -1; /* invalid option */ 440 default: return -1; /* invalid option */
438 } 441 }
439 } 442 }
440 return 0; 443 return i;
441} 444}
442 445
443static int runargs(lua_State *L, char **argv, int n) 446static int runargs(lua_State *L, char **argv, int argn)
444{ 447{
445 int i; 448 int i;
446 for (i = 1; i < n; i++) { 449 for (i = 1; i < argn; i++) {
447 if (argv[i] == NULL) continue; 450 if (argv[i] == NULL) continue;
448 lua_assert(argv[i][0] == '-'); 451 lua_assert(argv[i][0] == '-');
449 switch (argv[i][1]) { /* option */ 452 switch (argv[i][1]) {
450 case 'e': { 453 case 'e': {
451 const char *chunk = argv[i] + 2; 454 const char *chunk = argv[i] + 2;
452 if (*chunk == '\0') chunk = argv[++i]; 455 if (*chunk == '\0') chunk = argv[++i];
@@ -460,10 +463,10 @@ static int runargs(lua_State *L, char **argv, int n)
460 if (*filename == '\0') filename = argv[++i]; 463 if (*filename == '\0') filename = argv[++i];
461 lua_assert(filename != NULL); 464 lua_assert(filename != NULL);
462 if (dolibrary(L, filename)) 465 if (dolibrary(L, filename))
463 return 1; /* stop if file fails */ 466 return 1;
464 break; 467 break;
465 } 468 }
466 case 'j': { /* LuaJIT extension */ 469 case 'j': { /* LuaJIT extension. */
467 const char *cmd = argv[i] + 2; 470 const char *cmd = argv[i] + 2;
468 if (*cmd == '\0') cmd = argv[++i]; 471 if (*cmd == '\0') cmd = argv[++i];
469 lua_assert(cmd != NULL); 472 lua_assert(cmd != NULL);
@@ -471,11 +474,11 @@ static int runargs(lua_State *L, char **argv, int n)
471 return 1; 474 return 1;
472 break; 475 break;
473 } 476 }
474 case 'O': /* LuaJIT extension */ 477 case 'O': /* LuaJIT extension. */
475 if (dojitopt(L, argv[i] + 2)) 478 if (dojitopt(L, argv[i] + 2))
476 return 1; 479 return 1;
477 break; 480 break;
478 case 'b': /* LuaJIT extension */ 481 case 'b': /* LuaJIT extension. */
479 return dobytecode(L, argv+i); 482 return dobytecode(L, argv+i);
480 default: break; 483 default: break;
481 } 484 }
@@ -508,45 +511,57 @@ static int pmain(lua_State *L)
508{ 511{
509 struct Smain *s = &smain; 512 struct Smain *s = &smain;
510 char **argv = s->argv; 513 char **argv = s->argv;
511 int script; 514 int argn;
512 int flags = 0; 515 int flags = 0;
513 globalL = L; 516 globalL = L;
514 if (argv[0] && argv[0][0]) progname = argv[0]; 517 if (argv[0] && argv[0][0]) progname = argv[0];
515 LUAJIT_VERSION_SYM(); /* linker-enforced version check */ 518
516 script = collectargs(argv, &flags); 519 LUAJIT_VERSION_SYM(); /* Linker-enforced version check. */
517 if (script < 0) { /* invalid args? */ 520
521 argn = collectargs(argv, &flags);
522 if (argn < 0) { /* Invalid args? */
518 print_usage(); 523 print_usage();
519 s->status = 1; 524 s->status = 1;
520 return 0; 525 return 0;
521 } 526 }
527
522 if ((flags & FLAGS_NOENV)) { 528 if ((flags & FLAGS_NOENV)) {
523 lua_pushboolean(L, 1); 529 lua_pushboolean(L, 1);
524 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 530 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
525 } 531 }
526 lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ 532
527 luaL_openlibs(L); /* open libraries */ 533 /* Stop collector during library initialization. */
534 lua_gc(L, LUA_GCSTOP, 0);
535 luaL_openlibs(L);
528 lua_gc(L, LUA_GCRESTART, -1); 536 lua_gc(L, LUA_GCRESTART, -1);
537
538 createargtable(L, argv, s->argc, argn);
539
529 if (!(flags & FLAGS_NOENV)) { 540 if (!(flags & FLAGS_NOENV)) {
530 s->status = handle_luainit(L); 541 s->status = handle_luainit(L);
531 if (s->status != 0) return 0; 542 if (s->status != 0) return 0;
532 } 543 }
544
533 if ((flags & FLAGS_VERSION)) print_version(); 545 if ((flags & FLAGS_VERSION)) print_version();
534 s->status = runargs(L, argv, (script > 0) ? script : s->argc); 546
547 s->status = runargs(L, argv, argn);
535 if (s->status != 0) return 0; 548 if (s->status != 0) return 0;
536 if (script) { 549
537 s->status = handle_script(L, argv, script); 550 if (s->argc > argn) {
551 s->status = handle_script(L, argv + argn);
538 if (s->status != 0) return 0; 552 if (s->status != 0) return 0;
539 } 553 }
554
540 if ((flags & FLAGS_INTERACTIVE)) { 555 if ((flags & FLAGS_INTERACTIVE)) {
541 print_jit_status(L); 556 print_jit_status(L);
542 dotty(L); 557 dotty(L);
543 } else if (script == 0 && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) { 558 } else if (s->argc == argn && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) {
544 if (lua_stdin_is_tty()) { 559 if (lua_stdin_is_tty()) {
545 print_version(); 560 print_version();
546 print_jit_status(L); 561 print_jit_status(L);
547 dotty(L); 562 dotty(L);
548 } else { 563 } else {
549 dofile(L, NULL); /* executes stdin as a file */ 564 dofile(L, NULL); /* Executes stdin as a file. */
550 } 565 }
551 } 566 }
552 return 0; 567 return 0;
@@ -555,7 +570,7 @@ static int pmain(lua_State *L)
555int main(int argc, char **argv) 570int main(int argc, char **argv)
556{ 571{
557 int status; 572 int status;
558 lua_State *L = lua_open(); /* create state */ 573 lua_State *L = lua_open();
559 if (L == NULL) { 574 if (L == NULL) {
560 l_message(argv[0], "cannot create state: not enough memory"); 575 l_message(argv[0], "cannot create state: not enough memory");
561 return EXIT_FAILURE; 576 return EXIT_FAILURE;