JS Internal Test Suite

* PURPOSE

This is a test suite primarily for testing the SpiderMonkey JIT, GC, and any
other internal mechanisms that are not visible to test262. All tests are run in
the JS shell.

In the future, we intend to migrate the "non262" jstests over to this framework.

* CONTINUOUS INTEGRATION

In CI, these tests will be run as part of the "SM(...)" set of jobs. They will
also be packaged up and then run via mozharness as separate test jobs on some
platforms. These will appear on treeherder as jobs starting with "Jit", eg
"Jit", "Jit3", "Jit-1proc3", etc.

Unlike jstests, we do not run jit-tests in the browser. All tests may assume
they are running in the JS shell environment.

* REQUIREMENTS

Python 3.9. This is already a standard requirement for building our tree.

* RUNNING THE TESTS

Basic usage:

    ./mach jit-test

from the top of the checkout. Directly invoking

    python jit_test.py <path-to-js-shell>

will also work. The progress bar shows [#tests passed, #tests failed, #tests
run] at the left. If all tests pass, the output is 'PASSED ALL'. The test suite
can be interrupted at any time with Ctrl+C and partial results will be printed.

To run only the basic tests, not including the slow tests:

    ./mach jit-test <path-to-js-shell> basic

For more options:

    ./mach jit-test -- -h

or

    python jit_test.py -h

for the jit-test harness options, or

    ./mach jit-test -h

for the mach driver's options (eg --cgc).

* CREATING NEW TESTS

Simply create a JS file under the 'tests/' directory. Most tests should go in
'tests/basic/'.

All tests are run with 'lib/prologue.js' included first on the command line. The
command line also creates a global variable 'libdir' that is set to the path
of the 'lib' directory. To include a file 'foo.js' from the lib directory in a
test case:

    load(libdir + 'foo.js')

* TEST METALINES

The first line of a test case can contain a special comment controlling how the
test is run. For example:

    // |jit-test| allow-oom; --no-threads

The general format in EBNF is:

    metaline  ::= cookie { item ";" }
    cookie    ::= "|jit-test|"
    item      ::= flag | attribute

    flag      ::= "slow" | "heavy" | "allow-oom" | "allow-unhandlable-oom" |
                  "allow-overrecursed" | "valgrind" | "tz-pacific" | "module" |
                  "crash" | "test-also=" values | "test-join=" values |
                  "--" switch | "-P" pref

    attribute ::= name ":" value
    name      ::= "error" | "exitstatus" | "thread-count" | "include" |
                  "local-include" | "skip-if" | "skip-variant-if"
    value     ::= <string>
    values    ::= <whitespace-separated-strings>
    switch    ::= <string>
    pref      ::= <string>

The metaline may appear anywhere in the first line of the file: this allows it
to be placed inside any kind of comment.

The meaning of the items:

    slow              Test runs slowly. Do not run if the --no-slow option is given.
    heavy             Test is heavy and should not be run in parallel with other tests.
    allow-oom         If the test runs out of memory, it counts as passing.
    allow-unhandlable-oom  Allow unhandlable OOM errors (used for testing OOM handling).
    allow-overrecursed     Allow over-recursion errors.
    valgrind          Run test under valgrind.
    tz-pacific        Always run test with the Pacific time zone (TZ=PST8PDT).
    module            Test file is a module.
    crash             Test is expected to crash (only allowed in self-test).
    test-also=        Run the test with additional configurations (space-separated).
    test-join=        Join multiple tests together (space-separated).

    error             The test should be considered to pass iff it throws the
                      given JS exception.
    exitstatus        The test should exit with the given status value (an integer).
    thread-count      Set the number of threads for the test.
    include           Include additional library files.
    local-include     Include additional script files from the test directory.
    skip-if           Skip test if the condition is true.
    skip-variant-if   Skip specific test variant if the condition is true (format: variant,condition).

    --SWITCH          Pass --SWITCH through to js
    -P pref=value     Set a preference (e.g., -P pref=value)

* END
