The JavaScript compiler is implemented in the JavaScript language.
Because the JavaScript language does not have namespaces, the compiler
has been coded to a fixed part of the global namespace. All global
symbols the compiler uses, start with the prefix `JSC$
'. This
prefix is reserved for the interpreter and users must not define any
symbols or functions starting with that prefix.
The compiler compiles JavaScript source code to byte-code and it returns a fixed byte-code file as the result. This result file (or data block) can be passed to the virtual machine for execution.
The compiler has three stages. The first stage parse the input stream and create a syntax tree for the input. The second stage transforms the syntax tree to a list of assembler operations. The third stage converts the symbolic assembler instructions to byte-code operands.
Depending on the compilation options, the compiler performs different optimizations during the compilation. The basic optimizations include constant folding(1), peephole optimization, and optimization of jumps to jump instructions. During the batch-compilation (when compiling a JavaScript source file `.js' to byte-code file `.jsc') the compiler performns heavier optimizations to minimize the size of the generated byte-code file, and to speed up some operations.
null
, symbolic assembler output is
saved to that file. If argument bc_file is not null
, the
byte-code output is saved to that file.
The function returns a string that holds the byte-code output for the source file.
null
, symbolic assembler output is
saved to that file. If argument bc_file is not null
, the
byte-code output is saved to that file.
The function returns a string that holds the byte-code output for the source code.
In both functions, the argument flags specify the verbosity, warning, and optimization levels of the compilation. The following values can be given to flags:
JSC$FLAG_VERBOSE
JSC$FLAG_ANNOTATE_ASSEMBLER
JSC$FLAG_GENERATE_DEBUG_INFO
JSC$FLAG_GENERATE_EXECUTABLE_BC_FILES
JSC$FLAG_OPTIMIZE_PEEPHOLE
JSC$FLAG_OPTIMIZE_JUMPS
JSC$FLAG_OPTIMIZE_BC_SIZE
JSC$FLAG_OPTIMIZE_HEAVY
JSC$FLAG_OPTIMIZE_MASK
JSC$FLAG_WARN_UNUSED_ARGUMENT
JSC$FLAG_WARN_UNUSED_VARIABLE
JSC$FLAG_WARN_SHADOW
JSC$FLAG_WARN_WITH_CLOBBER
JSC$FLAG_WARN_MISSING_SEMICOLON
JSC$FLAG_WARN_STRICT_ECMA
JSC$FLAG_WARN_DEPRECATED
JSC$FLAG_WARN_MASK
The compiler entry points can be called from JavaScript and C programs.
For example, they are used extensively to implement the JavaScript API,
described in the `js.h' file. The following example shows how a
C-string, containing JavaScript code, can be compiled and executed.
Similar function can be found from the JavaScript API implementing the
js_eval()
function.
int eval_code (JSInterpPtr interp, char *code); { JSNode argv[5]; int i = 0; int result; ByteCode *bc; /* Compile the code. */ /* Argument count. */ argv[i].type = JS_INTEGER; argv[i].u.vinteger = 4; i++; /* Source for the compiler. */ js_make_static_string (interp->vm, &argv[i], code, strlen (code)); i++; /* Flags. */ argv[i].type = JS_INTEGER; argv[i].u.vinteger = JSC_FLAG_VERBOSE; argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_MASK; argv[i].u.vinteger |= JSC_FLAG_WARN_MASK; i++; /* Assembler file. */ argv[i].type = JS_NULL; i++; /* Byte-code file. */ argv[i].type = JS_NULL; i++; /* Call the compiler entry point. */ result = js_vm_apply (interp->vm, "JSC$compile_string", i, argv); if (result == 0) return 0; bc = js_bc_read_data (interp->vm->exec_result.u.vstring->data, interp->vm->exec_result.u.vstring->len); /* And finally, execute it. */ result = js_vm_execute (interp->vm, bc); /* Free the byte-code. */ js_bc_free (bc); return result; }
Go to the first, previous, next, last section, table of contents.