Go to the first, previous, next, last section, table of contents.


JavaScript Compiler

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.

Public Entry Points

Function: JSC$compile_file (name, flags, asm_file, bc_file)
Compile JavaScript source file name according to flags. If argument asm_file is not 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.

Function: JSC$compile_string (string, flags, asm_file, bc_file)
Compile JavaScript source code string according to flags. If argument asm_file is not 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
turns on diagnostic messages
JSC$FLAG_ANNOTATE_ASSEMBLER
add original JavaScript source lines to the generated assembler listing
JSC$FLAG_GENERATE_DEBUG_INFO
generate debugging information to the byte-code file
JSC$FLAG_GENERATE_EXECUTABLE_BC_FILES
add execute permissions to the generated byte-code files
JSC$FLAG_OPTIMIZE_PEEPHOLE
perform peephole optimization
JSC$FLAG_OPTIMIZE_JUMPS
perform optimization for jumps to jump instructions
JSC$FLAG_OPTIMIZE_BC_SIZE
optimize the size of the genated byte-code file
JSC$FLAG_OPTIMIZE_HEAVY
perform optimizations which require liveness analyzing of the variables
JSC$FLAG_OPTIMIZE_MASK
mask to turn on all optimizations
JSC$FLAG_WARN_UNUSED_ARGUMENT
warn if an argument of a function is unused in the function body
JSC$FLAG_WARN_UNUSED_VARIABLE
warn in a variable is defined but it is not used in the function body
JSC$FLAG_WARN_SHADOW
warn if a variable declaration shadows a parameter of a function
JSC$FLAG_WARN_WITH_CLOBBER
warn if a symbol with-lookup is clobbered because the symbol is defined to be a local variable or a function argument
JSC$FLAG_WARN_MISSING_SEMICOLON
warn if a semicolon is missing from the input. The missing semicolons are inserted during the parsing by the automatic semicolon inserting. However, since the missing semicolons show bad programming style, this option will warn about them.
JSC$FLAG_WARN_STRICT_ECMA
warn about things that are supported by this implementation, but are not allowed by the ECMAScript standard
JSC$FLAG_WARN_DEPRECATED
warn if deprecated features has been used in the source code
JSC$FLAG_WARN_MASK
mask to turn on all warnings

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.