3 * Copyright (c) 1998 New Generation Software (NGS) Oy
5 * Author: Markku Rossi <mtr@ngs.fi>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
26 * $Source: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/main.c,v $
42 #else /* not HAVE_STDC_HEADERS */
56 #endif /* not HAVE_STDC_HEADERS */
70 * -a, --annotate-assembler
72 * Annotate generated assembler listing with the original source code.
75 int annotate_assembler
= 0;
80 * Compile all given JavaScript files to byte-code and save the result
87 * -d METHOD, --dispatch=METHOD
89 * Use byte-code instruction dispatch method METHOD. Possible values are
90 * `switch', `switch-basic' and `jumps'.
93 JSVMDispatchMethod dispatch_method
= JS_VM_DISPATCH_JUMPS
;
96 * -e CODE, --eval=CODE
98 * Evaluate JavaScript code CODE.
104 * Print virtual machine events to the standard error.
111 * Use the next argument as the main source file and pass all
112 * remaining arguments to it through the ARGS array.
118 * Generate debugging information to the generated byte-code file.
120 int generate_debug_info
= 0;
125 * Print short help and exit successfully.
131 * Treat all following arguments, up to option -f / --file, as
132 * byte-code or JavaScript files and execute them. When option -f, --file
133 * is encountered, the next argument is the actual main source file that
134 * is executed with the remaining arguments.
140 * Do not define compiler in the interpreter. Options makes the
141 * interpreter a pure virtual machine that can't compile any JavaScript
148 * -O [LEVEL], --optimize[=LEVEL]
150 * Optimize at level LEVEL. The default level for batch-compile is 1.
151 * Value 0 disable optimization.
157 * -r OPTION, --secure=OPTIONS
159 * Turn on security option OPTION.
162 int secure_builtin_file
= 0;
163 int secure_builtin_system
= 0;
166 * -s SIZE, --stack-size=SIZE
168 * Set the virtual machine stack size to SIZE.
170 unsigned int stack_size
= 2048;
175 * Compile al given JavaScript files to JavaScript assembler and save the
184 * Print stack trace on error.
187 int stacktrace_on_error
= 0;
192 * Tell more about what we do.
195 unsigned int verbose
= 0;
200 * Print version information and exit successfully.
204 * -W OPTION, --compiler-option=OPTION
206 * Set compiler option OPTION.
209 int warn_deprecated
= 0;
210 int warn_unused_argument
= 0;
211 int warn_unused_variable
= 1;
214 int warn_with_clobber
= 1;
215 int warn_missing_semicolon
= 0;
216 int warn_strict_ecma
= 0;
221 * Generate executable byte-code files.
223 int generate_executable_bc_files
= 0;
230 static struct option long_options
[] =
232 {"annotate-assembler", no_argument
, 0, 'a'},
233 {"compile", no_argument
, 0, 'c'},
234 {"dispatch", required_argument
, 0, 'd'},
235 {"eval", required_argument
, 0, 'e'},
236 {"events", no_argument
, 0, 'E'},
237 {"file", no_argument
, 0, 'f'},
238 {"debug", no_argument
, 0, 'g'},
239 {"help", no_argument
, 0, 'h'},
240 {"load", no_argument
, 0, 'l'},
241 {"no-compiler", no_argument
, 0, 'N'},
242 {"optimize", optional_argument
, 0, 'O'},
243 {"secure", required_argument
, 0, 'r'},
244 {"stack-size", required_argument
, 0, 's'},
245 {"no-assemble", no_argument
, 0, 'S'},
246 {"stacktrace", no_argument
, 0, 't'},
247 {"verbose", no_argument
, 0, 'v'},
248 {"version", no_argument
, 0, 'V'},
249 {"compiler-option", required_argument
, 0, 'W'},
250 {"executable", no_argument
, 0, 'x'},
255 /* Compiler options. */
257 /* Flags for options. */
258 #define JSC_RUNTIME 0x01
259 #define JSC_WALL 0x02
260 #define JSC_PEDANTIC 0x04
261 #define JSC_LINT 0x08
268 } compiler_options
[] =
270 {"deprecated", &warn_deprecated
, JSC_WALL
},
271 {"unused-argument", &warn_unused_argument
, JSC_WALL
},
272 {"unused-variable", &warn_unused_variable
, JSC_WALL
},
273 {"undefined", &warn_undef
, JSC_RUNTIME
},
274 {"shadow", &warn_shadow
, JSC_WALL
},
275 {"with-clobber", &warn_with_clobber
, JSC_WALL
},
276 {"missing-semicolon", &warn_missing_semicolon
, JSC_PEDANTIC
},
277 {"strict-ecma", &warn_strict_ecma
, JSC_LINT
},
284 * Prototypes for static functions.
287 static void handle_compiler_option (char *name
);
289 static JSInterpPtr
create_interp (void);
291 static void usage (void);
292 static void version (void);
299 main (int argc
, char *argv
[])
301 JSInterpPtr interp
= NULL
;
305 /* Get program's name. */
306 program
= strrchr (argv
[0], '/');
312 /* Make getopt_long() to use our modified program name. */
315 /* Parse arguments. */
319 int option_index
= 0;
321 c
= getopt_long (argc
, argv
, "acd:e:EfghlNO::r:s:StvVW:x",
322 long_options
, &option_index
);
328 case 'a': /* --annotate-assembler */
329 annotate_assembler
= 1;
332 case 'c': /* --compile */
336 case 'd': /* --dispatch */
337 if (strcmp (optarg
, "switch-basic") == 0)
338 dispatch_method
= JS_VM_DISPATCH_SWITCH_BASIC
;
339 else if (strcmp (optarg
, "switch") == 0)
340 dispatch_method
= JS_VM_DISPATCH_SWITCH
;
341 else if (strcmp (optarg
, "jumps") == 0)
342 dispatch_method
= JS_VM_DISPATCH_JUMPS
;
345 fprintf (stderr
, "%s: illegal dispatch method `%s'\n",
351 case 'e': /* --eval */
353 interp
= create_interp ();
355 if (!js_eval (interp
, optarg
))
357 fprintf (stderr
, "%s: eval failed: %s\n", program
,
358 js_error_message (interp
));
363 case 'E': /* --events */
367 case 'f': /* --file */
370 no_argument_for_file
:
371 fprintf (stderr
, "%s: no arguments after option --file\n",
378 case 'g': /* --debug */
379 generate_debug_info
= 1;
382 case 'h': /* --help */
387 case 'l': /* --load */
392 case 'N': /* --no-compiler */
396 case 'O': /* --optimize */
398 optimize
= atoi (optarg
);
401 case 'r': /* --secure */
402 if (strcmp (optarg
, "file") == 0)
403 secure_builtin_file
= 1;
404 else if (strcmp (optarg
, "system") == 0)
405 secure_builtin_system
= 1;
408 fprintf (stderr
, "%s: unknown security option `%s'\n",
414 case 's': /* --stack-size */
415 stack_size
= atoi (optarg
);
418 case 'S': /* --no-assemble */
422 case 't': /* --stacktrace */
423 stacktrace_on_error
= 1;
426 case 'v': /* --verbose */
430 case 'V': /* --version */
435 case 'W': /* --compiler-option */
436 handle_compiler_option (optarg
);
439 case 'x': /* --executable */
440 generate_executable_bc_files
= 1;
444 fprintf (stderr
, "Try `%s --help' for more information.\n",
450 printf ("Hey! main() didn't handle option \"%c\" (%d)", c
, c
);
452 printf (" with arg %s", optarg
);
461 interp
= create_interp ();
463 /* Handle loading here. */
466 for (; optind
< argc
; optind
++)
468 if (strcmp (argv
[optind
], "-f") == 0
469 || strcmp (argv
[optind
], "--file") == 0)
473 goto no_argument_for_file
;
478 if (!js_eval_file (interp
, argv
[optind
]))
480 fprintf (stderr
, "%s: loading of file `%s' failed:\n%s\n",
481 program
, argv
[optind
], js_error_message (interp
));
487 /* Let's see what we have to do. */
493 * Treat all remaining arguments as JavaScript files and compile them.
496 for (; optind
< argc
; optind
++)
498 /* Create name for the byte-code file. */
500 jscname
= malloc (strlen (argv
[optind
]) + 5);
501 assert (jscname
!= NULL
);
502 strcpy (jscname
, argv
[optind
]);
504 cp
= strrchr (jscname
, '.');
506 strcpy (++cp
, "jsc");
508 strcat (jscname
, ".jsc");
511 printf ("%s: compiling `%s' to `%s'\n", program
,
512 argv
[optind
], jscname
);
514 if (!js_compile (interp
, argv
[optind
], NULL
, jscname
))
516 fprintf (stderr
, "%s\n", js_error_message (interp
));
523 else if (no_assemble
)
527 /* Compile argument files to assembler. */
528 for (; optind
< argc
; optind
++)
530 /* Create name for the assembler file. */
532 jasname
= malloc (strlen (argv
[optind
]) + 5);
533 assert (jasname
!= NULL
);
534 strcpy (jasname
, argv
[optind
]);
536 cp
= strrchr (jasname
, '.');
538 strcpy (++cp
, "jas");
540 strcat (jasname
, ".jas");
543 printf ("%s: compiling `%s' to `%s'\n", program
,
544 argv
[optind
], jasname
);
546 if (!js_compile (interp
, argv
[optind
], jasname
, NULL
))
548 fprintf (stderr
, "%s\n", js_error_message (interp
));
555 else if (optind
< argc
)
557 char *main_file
= argv
[optind
];
562 * Assume that <main_file> contains JavaScript (or byte-code) and
563 * execute it. All the remaining arguments are passed to the
564 * interpreter through the ARGS array.
567 /* Save all remaining arguments to ARGS */
568 js_type_make_array (interp
, &args
, argc
- optind
);
570 for (i
= 0; optind
+ i
< argc
; i
++)
571 js_type_make_string (interp
, &args
.u
.array
->data
[i
],
572 argv
[optind
+ i
], strlen (argv
[optind
+ i
]));
574 js_set_var (interp
, "ARGS", &args
);
576 if (!js_eval_file (interp
, main_file
))
578 fprintf (stderr
, "%s: evaluation of file `%s' failed:\n%s\n",
579 program
, main_file
, js_error_message (interp
));
584 js_destroy_interp (interp
);
587 /* Use with JS_DEBUG_MEMORY_LEAKS in jsint.h. */
588 js_alloc_dump_blocks ();
600 is_prefix (char *prefix
, char *str
)
604 for (i
= 0; prefix
[i
] && str
[i
] && prefix
[i
] == str
[i
]; i
++)
614 handle_compiler_option (char *name
)
621 if (name
[0] == 'n' && name
[1] == 'o' && name
[2] == '-')
627 for (i
= 0; compiler_options
[i
].name
; i
++)
631 if ((was_prefix
= is_prefix (name
, compiler_options
[i
].name
))
632 || (strcmp (name
, "runtime") == 0
633 && (compiler_options
[i
].flags
& JSC_RUNTIME
))
634 || (strcmp (name
, "all") == 0
635 && (compiler_options
[i
].flags
& JSC_WALL
))
636 || (strcmp (name
, "pedantic") == 0
637 && (compiler_options
[i
].flags
& (JSC_WALL
| JSC_PEDANTIC
))))
639 *compiler_options
[i
].option
= value
;
646 fprintf (stderr
, "set %s to %d\n", compiler_options
[i
].name
,
654 fprintf (stderr
, "%s: unknown compiler option `-W%s%s'\n", program
,
655 value
? "" : "no-", name
);
660 fprintf (stderr
, "%s: ambiguous compiler option `-W%s%s'\n",
661 program
, value
? "" : "no-", name
);
668 show_events_hook (int event
, void *context
)
674 case JS_EVENT_OPERAND_COUNT
:
675 event_name
= "operand count";
678 case JS_EVENT_GARBAGE_COLLECT
:
679 event_name
= "garbage collect";
683 event_name
= "unknown";
687 fprintf (stderr
, "[%s: %s]\n", program
, event_name
);
696 JSInterpOptions options
;
699 js_init_default_options (&options
);
701 options
.stack_size
= stack_size
;
702 options
.dispatch_method
= dispatch_method
;
703 options
.verbose
= verbose
;
705 options
.no_compiler
= no_compiler
;
706 options
.stacktrace_on_error
= stacktrace_on_error
;
708 options
.secure_builtin_file
= secure_builtin_file
;
709 options
.secure_builtin_system
= secure_builtin_system
;
711 options
.annotate_assembler
= annotate_assembler
;
712 options
.debug_info
= generate_debug_info
;
713 options
.executable_bc_files
= generate_executable_bc_files
;
715 options
.warn_unused_argument
= warn_unused_argument
;
716 options
.warn_unused_variable
= warn_unused_variable
;
717 options
.warn_undef
= warn_undef
;
718 options
.warn_shadow
= warn_shadow
;
719 options
.warn_with_clobber
= warn_with_clobber
;
720 options
.warn_missing_semicolon
= warn_missing_semicolon
;
721 options
.warn_strict_ecma
= warn_strict_ecma
;
722 options
.warn_deprecated
= warn_deprecated
;
724 /* As a default, no optimization */
725 options
.optimize_peephole
= 0;
726 options
.optimize_jumps_to_jumps
= 0;
727 options
.optimize_bc_size
= 0;
728 options
.optimize_heavy
= 0;
732 options
.optimize_peephole
= 1;
733 options
.optimize_jumps_to_jumps
= 1;
734 options
.optimize_bc_size
= 1;
739 options
.optimize_heavy
= 1;
745 options
.hook
= show_events_hook
;
746 options
.hook_operand_count_trigger
= 1000000;
749 interp
= js_create_interp (&options
);
752 fprintf (stderr
, "%s: couldn't create interpreter\n", program
);
756 /* And finally, define the requested modules. */
759 if (!js_define_module (interp
, js_ext_JS
))
760 fprintf (stderr
, "%s: warning: couldn't create the JS extension\n",
765 if (!js_define_module (interp
, js_ext_curses
))
766 fprintf (stderr
, "%s: warning: couldn't create the curses extension\n",
771 if (!js_define_module (interp
, js_ext_MD5
))
772 fprintf (stderr
, "%s: warning: couldn't create the MD5 extension\n",
784 Usage: %s [OPTION]... FILE [ARGUMENT]...\n\
785 Mandatory arguments to long options are mandatory for short options too.\n\
786 -a, --annotate-assembler annotate generated assembler listing with\n\
787 the original source code\n\
788 -c, --compile compile JavaScript input file to byte-code\n\
789 and save the result to the file `FILE.jsc'\n\
790 -d, --dispatch=METHOD use method METHOD for byte-code instruction\n\
792 -e, --eval=CODE evaluate JavaScript code CODE\n\
793 -E, --events print interpreter events\n\
794 -f, --file evaluate the next argument file and pass\n\
795 all remaining arguments to the interpreter\n\
796 through the ARGS array\n\
797 -g, --debug generate debugging information\n\
798 -h, --help print this help and exit\n\
799 -l, --load evaluate argument files until option `-f',\n\
800 `--file' is encountered\n\
801 -N, --no-compiler do not define compiler to the JavaScript\n\
803 -O, --optimize[=LEVEL] optimize at level LEVEL\n\
804 -r, --secure=OPTION turn on security option OPTION\n\
805 -s, --stack-size=SIZE set the interpreter stack size to SIZE nodes\n\
806 -S, --assembler compile JavaScript intput file to assembler\n\
807 and save the result to the file `FILE.jas'\n\
808 -t, --stacktrace print stacktrace on error\n\
809 -v, --verbose tell what the interpreter is doing\n\
810 -V, --version print version number\n\
811 -W, --compiler-option=OPTION\n\
812 set compilation option OPTION\n\
813 -x, --executable generate executable byte-code files\n",
816 printf ("\nReport bugs to mtr@ngs.fi.\n");
823 printf ("NGS JavaScript Interpter %s\n\
824 Copyright (C) 1998 New Generation Software (NGS) Oy.\n\
825 NGS JavaScript Interpreter comes with NO WARRANTY, to the extent\n\
826 permitted by law. You may redistribute copies of NGS JavaScript\n\
827 Interpreter under the terms of the GNU Library General Public License.\n\
828 For more information about these matters, see the files named COPYING.\n\