     [file version.texi not included]

This file documents NGS JavaScript interpreter VERSION

Copyright (C) 1998 New Generation Software (NGS) Oy

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Foundation.

NGS JavaScript Interpreter
**************************

This file documents the NGS JavaScript interpreter.  This edition documents version VERSION.

Introduction
************

  * overall

  * design goals

  * structure: virtual machine, JSC$, JS glue

NGS JavaScript Language
***********************

Language
========

Lexical Conventions
-------------------

White Space
...........

Comments
........

Reserved Words
..............

Identifiers
...........

Punctuators
...........

Literals
........

Automatic Semicolon Insertion
.............................

Certain ECMAScript statements must be terminated with a semicolon.  Such a semicolon may always appear explicitly in the source text.  For pain of the compiler implementator, however, such semicolons may be omitted from the source text in certain situations.  These situations are described in details in the ECMA-262 Version 2 draft 22-Apr-98 standard.  Here is mtr@ngs.fi's interpretation of the rules:

Insert semicolons as you would do in the C language.  Now, you can omit them:

 1. before '}' character

 2. from the end of the line

 3. from the end of the file

The automatic semicolon insertion sets some restrictions how you can insert whitespace to you code.  You can't insert line breaks:

 1. between LEFTHANDSIDEEXPRESSION and ++ or -- operator

 2. between return and the returned EXPRESSION

Function Definition
-------------------

Statements
----------

Block
.....

Variable Statement
..................

Empty Statement
...............

The if Statement
................

The do...while Statement
........................

The while Statement
...................

The for Statement
.................

The for...in Statement
......................

The continue Statement
......................

The break Statement
...................

The return Statement
....................

The with Statement
..................

The syntax of the with-statement is:

     with (EXPR) STATEMENT

     with (Math)
       {
         result = sin (PI);
         result -= tan (45);
       }

The switch Statement
....................

Labeled Statements
..................

The throw Statement
...................

The try Statement
.................

Expressions
-----------

Primary Expressions
...................

Left-Hand-Side Expressions
..........................

Postfix Expressions
...................

Unary Operators
...............

Multiplicative Operators
........................

Additive Operators
..................

Bitwise Shift Operators
.......................

Relational Operators
....................

Equality Operators
..................

Binary Bitwise Operators
........................

Binary Logical Operators
........................

Conditional Operator
....................

Assignment Operators
....................

Comma Operator
..............

Global Methods and Properties
=============================

Standard
     ECMA-262 Version 2 draft 22-Apr-98

 -- Property of Global: NaN
     The not a number value.

 -- Property of Global: Infinity
     The positive infinity value.

 -- Function: eval (any)

 -- Function: parseInt (string, radix)

 -- Function: parseFloat (string)

 -- Function: escape (string)

 -- Function: unescape (string)

 -- Function: isNaN (any)

 -- Function: isFinite (any)

 -- Function: debug (any)

     Standard
          Netscape JavaScript Reference 12-Dec-97

 -- Function: print (any[,...])

     Standard
          Netscape JavaScript Reference 12-Dec-97 ???

 -- Function: error (message)

     Standard
          Netscape JavaScript Reference 12-Dec-97 ???

 -- Function: float (any)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Function: int (any)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Function: isFloat (any)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Function: isInt (any)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Function: load (file...)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Function: loadClass (class_spec...)

     Standard
          NGS JavaScript Interpreter VERSION

     Extend interpreter by calling an initialization function from shared library CLASS_SPEC.  The argument CLASS_SPEC can be given in the following formats:

     LIBRARY:FUNCTION

          The argument LIBRARY specifies the shared library from which function FUNCTION is called.  The library specification can be given in absolute or relative formats.

     LIBRARY
          The argument LIBRARY specifies both the shared library, and the name of the entry function.  The name of the entry function is the name of the library, without the possible leading directory path and any suffixes.

          loadClass ("libexts.so:init_all");
          => CALL FUNCTION INIT_ALL FROM LIBRARY LIBEXTS.SO

          loadClass ("/usr/local/lib/libexts.so:init_all");
          => CALL FUNCTION INIT_ALL FROM LIBRARY /USR/LOCAL/LIB/LIBEXTS.SO

          loadClass ("/usr/local/lib/libdbexts.so");
          => CALL FUNCTION DBEXTS FROM LIBRARY /USR/LOCAL/LIB/LIBEXTS.SO

     The initialization function must be a void function that takes one argument that is a pointer to the interpreter.

          void
          entry (JSInterpPtr interp)
          {
            INITIALIZE EXTENSIONS USING NORMAL JS.H AND JSINT.H
            INTERFACES.
          }

 -- Function: callMethod (object, method, arguments)

     Standard
          NGS JavaScript Interpreter VERSION

     Call method METHOD from object OBJECT with arguments ARGUMENTS.

          callMethod (System.stdout, "writeln", ["Hello, world!"]);
          -| Hello, world!

Native Objects
==============

Array
-----

Standard
     ECMA-262 Version 2 draft 22-Apr-98

Incompatibilities

       * The toSource() method is missing.

       * The constructor doesn't set the [[Prototype]] and [[Class]] properties.

 -- Function: Array (count)
 -- Function: Array (item...)
     Do exactly the same as the expression new Array() called with the same arguments.

 -- Constructor: Array (count)
 -- Constructor: Array (item...)

     Create a new array object.  The first form creates a new array which length is COUNT.  All items are set to value undefined. The second form creates an array that contains the given items as its values.

          var a = new Array (5);
          a.length;
          => 5
          a.toString ();
          => undefined,undefined,undefined,undefined,undefined

          a = new Array (1, 2, "hello");
          a.length;
          => 3
          a.toString ();
          => 1,2,hello

 -- Method on Array: concat (array[, ...])
     Create a new array object from the items of the called array object and the argument arrays ARRAY, ....  The contents of the argument arrays are not modified.

          var a = new Array (1, 2, 3);
          var b = a.concat (new Array (4, 5));
          b.length;
          => 5;
          b.toString ();
          => 1,2,3,4,5

 -- Method on Array: join ([glue])
     Convert the array to a string.  Individual items of the array are combined with the string GLUE.  If the argument GLUE is omitted, string "," is used.

          var a = new Array (1, 2, "three");
          a.join ();
          => "1,2,three"

          a.join ("-");
          => "1-2-three"

 -- Method on Array: pop ()
     Remove the last item of the array.  The method returns the item removed. If the array is empty, value undefined is returned.

          a = new Array (1, 2, 3);
          a.pop ();
          => 3
          a.length;
          => 2

 -- Method on Array: push (any...)
     Insert items to the end of the array.  The method returns the last item pushed.

          a = new Array (1, 2);
          a.push (7);
          => 7
          a.push (7, 8, 9);
          => 9
          System.print (a.join (", "), "\n");
          -| 1, 2, 7, 7, 8, 9

 -- Method on Array: reverse ()
     Reverse the array.

          a = new Array (1, 2, 3);
          a.reverse ();
          System.print (a.join (""), "\n");
          -| 321

 -- Method on Array: shift ()
     Remove item from the beginning of the array.  The method returns the item removed, or value undefined if the array was empty.

          a = new Array (1, 2, 3);
          a.shift ();
          => 1

 -- Method on Array: slice (start[, end])
     Return a new array containing items between START (inclusively) and END (exclusively) in the array.  If the argument END is negative, it is counted from the end of the array.  If the argument END is omitted, the method extract items from the position START to the end of the array.

          a = new Array (1, 2, 3, 4, 5);
          b = a.slice (1, 4);
          System.print (b.join (", "), "\n");
          -| 2, 3, 4
          b = a.slice (1, -2);
          System.print (b.join (", "), "\n");
          -| 2, 3
          b = a.slice (2);
          System.print (b.join (", "), "\n");
          -| 3, 4, 5

 -- Method on Array: splice (index, remove[, any...])
     Modify array by removing old items and by inserting new ones.  The argument INDEX specifies the index from which the array is modified.  The argument REMOVE specifies how many old items are removed.  If the argument REMOVE is 0, no old items are removed and at least one new item must have been given.  After the items are removed, all remaining arguments are inserted after the position INDEX.

          var a = new Array (1, 2, 3);
          a.splice (1, 1);
          => 1, 3
          a.splice (1, 0, "new item");
          => 1, "new item", 2, 3

          var a = new Array (1, 2, 3, 4);
          a.splice (1, 2, "new item");
          => 1, "new item", 4

 -- Method on Array: sort ([sort_function])
     Sort the array to the order specified by the argument function SORT_FUNCTION.  The comparison function SORT_FUNCTION takes two arguments and it must return one of the following codes:

     -1
          the first argument items is smaller than the second item (must come before the second item)

     0
          the items are equal

     1
          the first argument item is bigger than the second item (it must come after the second item)

     If the argument SORT_FUNCTION is omitted, the items are sorted to an alphabetical (lexicographical) order.

          a = new Array ("Jukka-Pekka", "Jukka", "Kari", "Markku");
          a.sort ();
          System.print (a, "\n");
          -| Jukka,Jukka-Pekka,Kari,Markku
          a = new Array (1, 2, 10, 20, 100, 200);
          a.sort ();
          System.stdout.writeln (a.toString ());
          -| 1,10,100,2,20,200

     The sort method is stable in that sense that, if the comparison function returns 0 for two items, their original order in the array is preserved. For example, if a list of person objects is sorted first by their names, and second by their ages, all persons with the same age will remain sorted in an alphabetical order.

          function by_age (a, b)
          {
            return a.age - b.age;
          }

          function by_name (a, b)
          {
            if (a.name < b.name)
              return -1;
            if (a.name > b.name)
              return 1;
            return 0;
          }

          function Person (name, age)
          {
            this.name = name;
            this.age = age;
          }

          a = new Array (new Person ("Smith", 30),
                         new Person ("Jones", 31),
                         new Person ("Bob", 30),
                         new Person ("Chris", 29));

          a.sort (by_name);
          a.sort (by_age);

          for (i in a)
            System.print (i.name, ", ", i.age, "\n");
          -| Chris, 29
          -| Bob, 30
          -| Smith, 30
          -| Jones, 31

 -- Method on Array: toSource ()

 -- Method on Array: toString ()
     Convert the array to a string.  The method converts each item of the array to string and combines them with the string ",".

          var a = new Array (1, "foo", 2, new Array (7, 8));
          a.toString ();
          => 1,foo,2,7,8

 -- Method on Array: unshift (any...)
     Insert items ANY... to the beginning of the array.  The method returns the new length of the array.

          a = new Array (1, 2, 3);
          System.print (a.unshift (7, 8, 9), "\n");
          -| 6

 -- Property of Array: length
     The length of the array.

          var a = new Array (1, 2);
          a.length;
          => 2
          a.push (3, 4, 5);
          a.length;
          => 5

Boolean
-------

Standard
     ECMA-262 Version 2 draft 22-Apr-98

Incompatibilities

       * The constructor doesn't set the [[Prototype]] and [[Class]] properties.

 -- Function: Boolean ()
     Return false.

 -- Function: Boolean (value)

 -- Constructor: Boolean ()
 -- Constructor: Boolean (value)
     Create a new boolean object.  If no arguments are given, the returned object will have value false.  If the argument VALUE is given, the initial value of the object is determined by the type of the argument and its value.  If the argument VALUE is undefined, null, false, "" (an empty string), or 0, the value of the object will be false.  All other values for the argument VALUE will set the initial value of the object to true.

 -- Method on Boolean: toString ()
     Return a string presentation of the boolean object.  The method will return string "true" or "false" according to the value of the object.

 -- Method on Boolean: valueOf ()

Date
----

Standard
     ECMA-262 Version 2 draft 22-Apr-98

Incompatibilities
     XXX Check all methods and properties.

 -- Function: MakeTime (hour, min, sec, ms)

 -- Function: MakeDay (year, month, date)

 -- Function: MakeDate (day, time)

 -- Function: TimeClip (time)

 -- Function: Date ([a1[, a2[, a3[, a4[, a5[, a6[, a7]]]]]]])
     When the Date constructor is called as a function, it ignores arguments A1...A7 and returns the result of expression:

          new Date ().toString()

 -- Constructor: Date ()
 -- Constructor: Date ("MONTH DAY, YEAR HOURS:MINUTES:SECONDS")
 -- Constructor: Date (YR_NUM, MO_NUM, DAY_NUM)
 -- Constructor: Date (YR_NUM, MO_NUM, DAY_NUM, HR_NUM, MIN_NUM, SEC_NUM)

 -- Static Method on Date: UTC (YEAR, MONTH, DAY, HRS, MIN, SEC)

 -- Method on Date: format (format)

 -- Method on Date: formatGMT (format)

 -- Method on Date: getDate ()

 -- Method on Date: getDay ()

 -- Method on Date: getHours ()

 -- Method on Date: getMinutes ()

 -- Method on Date: getMonth ()

 -- Method on Date: getSeconds ()

 -- Method on Date: getTime ()

 -- Method on Date: getTimezoneOffset ()

 -- Method on Date: getYear ()

 -- Method on Date: parse (string)

 -- Method on Date: setDate (day)

 -- Method on Date: setHours (hours)

 -- Method on Date: setMinutes (minutes)

 -- Method on Date: setMonths (months)

 -- Method on Date: setSeconds (seconds)

 -- Method on Date: setTime (time)

 -- Method on Date: setYear (year)

 -- Method on Date: toGMTString ()

 -- Method on Date: toLocaleString ()

File
----

Standard
     Netscape JavaScript Reference 12-Dec-97

Incompatibilities
     XXX Check all methods and properties.

 -- Constructor: File (path)

 -- Static Method on File: byteToString (byte)

 -- Static Method on File: chmod (path, mode)

     Standard
          NGS JavaScript Interpreter VERSION

     Change permissions of file PATH to MODE.  The modes are specifeid by or'ing the following values:

     04000
          set user ID on execution

     02000
          set group ID on execution

     01000
          sticky bit

     00400
          read by owner

     00200
          write by owner

     00100
          execute / search by owner

     00040
          read by group

     00020
          write by group

     00010
          execute / search by group

     00004
          read by others

     00002
          write by others

     00001
          execute / search by others

 -- Static Method on File: lstat (path)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Static Method on File: remove (path)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Static Method on File: rename (path)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Static Method on File: stat (path)

     Standard
          NGS JavaScript Interpreter VERSION

     Return statistics about the file FILE.  The method returns a 13 element array containing the statistics, or false if the file couldn't be inspected.

     The returned array contains the following items:

     dev
          Device that contains a directory entry for this file.

     ino
          Index of this file on its device.  A file is uniquely identified by specifying its dev and ino.

     mode
          The mode of the file.

     nlink
          The number of hard links to the file.

     uid
          The ID of the file owner.

     gid
          The ID of the file group.

     rdev
          The ID of the device.

     size
          The size of the file.

     atime
          The time when the data was last accessed.

     mtime
          The time when the data was last modified.

     ctime
          The time when the file status was last changed.

     blksize
          Preferred blocksize for file system I/O.

     blocks
          The number of blocks the file actually uses.

          fields = new Array ("dev", "ino", "mode", "nlink", "uid",
                              "gid", "rdev", "size", "atime",
                              "mtime", "ctime", "blksize", "blocks");

          var a = File.stat ("js");
          if (a)
            {
              var i;
              for (i = 0; i < a.length; i++)
                System.print (fields[i], "=", a[i], " ");
              System.print ("\n");
            }

          -| dev=655368 ino=370741 mode=33261 nlink=1 uid=201 gid=200
          -| rdev=2979328 size=731370 atime=893159080 mtime=893158537
          -| ctime=893158537 blksize=4096 blocks=1432

 -- Static Method on File: stringToByte (string)

 -- Method on File: open (mode)

     The argument MODE must have one of the following values:

     r[b]

     w[b]

     a[b]

     r+[b]

     w+[b]

     a+[b]

 -- Method on File: close ()

 -- Method on File: setPosition (position[, whence])

 -- Method on File: getPosition ()

 -- Method on File: eof ()

 -- Method on File: read (size)

 -- Method on File: readln ()

 -- Method on File: readByte ()

 -- Method on File: toString ()

 -- Method on File: write (string)

 -- Method on File: writeln (string)

 -- Method on File: writeByte (byte)

 -- Method on File: ungetByte (byte)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Method on File: flush ()

 -- Method on File: getLength ()

 -- Method on File: exists ()

 -- Method on File: error ()

 -- Method on File: clearError ()

 -- Property of File: autoFlush

     Standard
          NGS JavaScript Interpreter VERSION

     Flag that specifies whether the stream should automatically flush its buffers after a write.

 -- Property of File: bufferSize

     Standard
          NGS JavaScript Interpreter VERSION

     The I/O buffer size of the stream.  The buffer size can be changed at the runtime.

Directory
---------

Standard
     NGS JavaScript Interpreter VERSION

 -- Constructor: Directory (path)

 -- Method on Directory: close ()

 -- Method on Directory: open ()

 -- Method on Directory: read ()

 -- Method on Directory: rewind ()

 -- Method on Directory: seek (pos)

 -- Method on Directory: tell ()

Function
--------

Math
----

Standard
     ECMA-262 Version 2 draft 22-Apr-98

 -- Static Method on Math: abs (X)

 -- Static Method on Math: acos (X)

 -- Static Method on Math: asin (X)

 -- Static Method on Math: atan (X)

 -- Static Method on Math: atan2 (Y, X)

 -- Static Method on Math: ceil (X)

 -- Static Method on Math: cos (X)

 -- Static Method on Math: exp (X)

 -- Static Method on Math: floor (X)

 -- Static Method on Math: log (X)

 -- Static Method on Math: max (X, Y)

 -- Static Method on Math: min (X, Y)

 -- Static Method on Math: pow (X, Y)

 -- Static Method on Math: random ()

 -- Static Method on Math: round (X)

 -- Static Method on Math: seed (X)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Static Method on Math: sin (X)

 -- Static Method on Math: sqrt (X)

 -- Static Method on Math: tan (X)

 -- Static Property of Math: E

 -- Static Property of Math: LN10

 -- Static Property of Math: LN2

 -- Static Property of Math: LOG10E

 -- Static Property of Math: LOG2E

 -- Static Property of Math: PI

 -- Static Property of Math: SQRT1_2

 -- Static Property of Math: SQRT2

Number
------

Standard
     ECMA-262 Version 2 draft 22-Apr-98

 -- Function: Number()
     Return value 0.

 -- Function: Number (value)

 -- Constructor: Number ()
 -- Constructor: Number (VALUE)
     Create a new number object.  If no argument is given, the constructor returns value +0.  If the argument VALUE is given, the constructor returns ToNumber(VALUE).

          new Number ();
          => 0
          new Number (3.1415);
          => 3.1415
          new Number (true);
          => 1

 -- Method on Number: toString ([RADIX])
     Convert the number to its textual presentation.  If the argument RADIX is given, it specifies the radix to which the number is formatted.  If the argument RADIX is not given, it defaults to 10.

          System.stdout.writeln ((193).toString ());
          -| 193
          System.stdout.writeln ((193).toString (8));
          -| 301
          System.stdout.writeln ((193).toString (16));
          -| c1
          System.stdout.writeln ((193).toString (2));
          -| 11000001

 -- Method on Number: valueOf ()
     Return the value of the number object.

 -- Static Property of Number: MAX_VALUE

 -- Static Property of Number: MIN_VALUE

 -- Static Property of Number: NaN

 -- Static Property of Number: NEGATIVE_INFINITY

 -- Static Property of Number: POSITIVE_INFINITY

Object
------

Standard
     ECMA-262 Version 2 draft 22-Apr-98

Incompatibilities

       * The toString() and toSource() methods are missing.

       * The constructor doesn't set the [[Prototype]] and [[Class]] properties.

 -- Function: Object ([VALUE])

 -- Constructor: Object ([VALUE])
     Create a new object.

          var o = new Object ();

 -- Method on Object: toString ()

 -- Method on Object: toSource ()

 -- Method on Object: valueOf ()

RegExp
------

Standard
     ECMA-262 Version 2 draft 22-Apr-98

Incompatibilities

       * The regular expression engine -- taken from the GNU Emacs -- might not support all features that are required.

       * XXX Check all methods and properties.

 -- Constructor: RegExp (pattern[, flags])

     Create a new regular expression from string PATTERN.  The optional argument string FLAGS can contain the following options:

     i
          Ignore case; the matching is case-insensitive.

     g
          Global search.  This allows you to iterate over all matches of the expression by executing the exec method multiple times against the string.

 -- Method on RegExp: compile (PATTERN[, FLAGS])
     Create a new regular expression from string PATTERN using optional options FLAGS.  The method can be used to change the regular expression pattern or its flags in the regular expression object. The method returns an error if the string PATTERN do not specify a well-formed regular expression.

     Note!  All regular expressions are always compiled in this implementation.  This holds also for the expressions, created with the RegExp() constructor.

          var re = new RegExp ("ab*");
          re.compile ("ab*", "i");

 -- Method on RegExp: exec ([string])
     Match the expression against the string STRING.  If the argument STRING is omitted, the regular expression is matched against the RegExp.input string.  The method returns an array that holds the matched portions of the expression.

          var re = new RegExp ("d(b+)(d)", "ig");
          var a = re.exec ("cdbBdbsbz");
          a.toString ();
          => "dbBd,bB,d"

In the previous example, the result array a has the following items:

dbBd
     The substring that matched the regular expression.  This string can also be retrieved as RegExp.lastMatch.

bB
     The matched substring for the first parenthesized subexpression (b+).  This match can also be found as RegExp.$1.

d
     The matched substring for the second parentsized subexpression (d).  This match can also be found as RegExp.$2.

The option g of the regular expression can be used to iterate over multiple matches of the expression on at a time.  For example, the following code fragment searches for the expression a(b*) from the string str.  In the inial state -- when the expression is create with the constructor -- the object's lastIndex property is set to 0.  When the expression is matched against the string, the lastIndex property is updated to point to the next index from which the matching should be continued.  Therefore, the following example iterates over all matches in the string str.

     var re = new RegExp ("a(b*)", "g");
     var str = "abbcdefabh";
     while (a = re.exec (str))
       System.print ("Found ", a, ". Next match starts at ", re.lastIndex,
     		    ".\n");
     -| Found abb. Next match starts at 3.
     -| Found ab. Next match starts at 9.

The property REGEXP.lastIndex can also be set explicitly to start the matching from a pre-defined position.

 -- Method on RegExp: test ([string])
     Test whether the regular expression matches for the string STRING. If the argument STRING is omitted, the regular expression is tested against the RegExp.input string.

          var re = new RegExp ("fo*bar");
          re.test ("fbar");
          => true
          re.test ("fooBar");
          => false

          re = new RegExp ("fo*bar", "i");
          re.test ("FOObAR");
          => true

          RegExp.input = "#include <stdio.h>";
          re = new RegExp ("^#");
          re.test ();
          => true

 -- Static Property of RegExp: $1
 -- Static Property of RegExp: $2
 -- Static Property of RegExp: $3
 -- Static Property of RegExp: $4
 -- Static Property of RegExp: $5
 -- Static Property of RegExp: $6
 -- Static Property of RegExp: $7
 -- Static Property of RegExp: $8
 -- Static Property of RegExp: $9
     The matching substring for the n:th parenthesized subexpression.  If the latest regular expression didn't have that many parenthesized subexpressions, the property has value undefined.

 -- Static Property of RegExp: $_
 -- Static Property of RegExp: input
     The string against which the expression was tested.  The input property is also used, if no string argument was given for the test() or exec() methods.

          var str = file.readln ();
          re.test (str);
          RegExp.input;
          => THE STRING RETURNED BY THE FILE.READLN() METHOD.

 -- Static Property of RegExp: lastMatch
     The substring that matched the whole expression in the last regular expression matching.

 -- Static Property of RegExp: lastParen
     The last parenthesized subexpression of the last regular expression matching.

 -- Static Property of RegExp: leftContext
     The substring from the beginning of the input string to the beginning of the matching substring of the last regular expression.

          var re = new RegExp ("foo");
          var str = "garbage foo tail garbage";
          re.exec (str);
          RegExp.leftContext;
          => "garbage "

 -- Static Property of RegExp: multiline

 -- Static Property of RegExp: rightContext
     The substring from the end of the matching substring to the end the input string.

          var re = new RegExp ("foo");
          var str = "garbage foo tail garbage";
          re.exec (str);
          RegExp.rightContext;
          => " tail garbage"

 -- Property of RegExp: global
     Flag that tells if the option g was given for the constructor or for the compile method.

 -- Property of RegExp: ignoreCase
     Flat that tells if the option i was given for the construtor or for the compile method.

 -- Property of RegExp: lastIndex
     The index from which the matching is continued with the global (g) expressions.

 -- Property of RegExp: source
     The source string from which the regular expression object was created.

String
------

Standard
     ECMA-262 Version 2 draft 22-Apr-98

Incompatibilities

       * The constructor doesn't set the [[Prototype]] and [[Class]] properties.

 -- Constructor: String (string)
     Create a new string object and set its data to STRING.

          var str = new String ("Hello, world");
          => "Hello, world!"

 -- Static Method on String: fromCharCode (code...)
     Create a new string object from the character codes CODE....

          var str = String.fromCharCode (72, 101, 108, 108, 111, 33);
          => "Hello!"

 -- Static Method on String: pack (format, arg[, ...])

     Standard
          NGS JavaScript Interpreter VERSION

     Create a new string by packing values ARG... to a string according to the format string FORMAT.

     The format is a sequence of characters that specify the type of values as follows:

     C
          an unsigned char value

     n
          a short in "network" (big-endian) order

     N
          a long in "network" (big-endian) order

     d
          a double-precision float in the native format

 -- Method on String: append (string)

     Standard
          NGS JavaScript Interpreter VERSION

     Append string STRING to the end of the string object.  The string object must be a dynamic string, not a constant string literal.

          var str = new String ("");
          str.append ("foo");
          str.append ("-");
          str.append ("bar");
          => "foo-bar"

 -- Method on String: charAt (position)
     Create a new string that constains the character from position POSITION of the the string object.

          "foobar".charAt (3);
          => "b"

 -- Method on String: charCodeAt (position)
     Return the code of the character at position POSITION in the string object.

          "foobar".charCodeAt (3);
          => 98

 -- Method on String: concat (STRING[, ...])
     Create a new string by appending the argument strings STRING, ... to the end of the string object.

          "foo".concat ("bar");
          => "foobar"

 -- Method on String: crc32 ()

     Standard
          NGS JavaScript Interpreter VERSION

     Count a 32-bit CRC of the string.

          var str = "Hello, world!";
          System.print ("CRC32 of \"", str, "\" is ",
                        str.crc32 ().toString (16), ".\n");
          -| CRC32 of "Hello, world!" is e4928064.

 -- Method on String: indexOf (string[, start_index])
     Return the index of the first substring of STRING within the string object, or -1 if the string didn't contain the substring.  The optional argument START_INDEX can be used to specify the index from which the searching is started.

          var str = "foobar foo bar foo";
          str.indexOf ("foo");
          => 0
          str.indexOf (" foo");
          => 6
          str.indexOf ("foo", 1);
          => 7
          str.indexOf ("Foo");
          => -1

 -- Method on String: lastIndexOf (string[, start_index])
     Return the the index of the last substring of STRING within the string object, or -1 if the string didn't contain the substring.  The optional argument START_INDEX can be used to specify the index from which the searching is started.

          var str = "foobar foo bar foo";
          str.lastIndexOf ("foo");
          => 15
          str.lastIndexOf ("bar");
          => 11
          str.lastIndexOf ("foo", 14);
          => 7
          str.lastIndexOf ("Foo");
          => -1

 -- Method on String: match (regexp)

 -- Method on String: replace (regexp, substitution)

 -- Method on String: search (regexp)

 -- Method on String: slice (start[, end])

 -- Method on String: split (separtor[, limit])

 -- Method on String: substr (start[, length])

 -- Method on String: substring (start[, end])

 -- Method on String: toLowerCase ()
     Create a new string which contents is the data of the string object, converted to the lower case.

          "FoObAr".toLowerCase ();
          => "foobar"

 -- Method on String: toUpperCase ()
     Create a new string which contents is the data of the string object, converted to the upper case.

          "FoObAr".toUpperCase ();
          => "FOOBAR"

 -- Method on String: unpack (format)

     Standard
          NGS JavaScript Interpreter VERSION

 -- Property of String: length
     The length of the string.

          "foobar".length;
          => 6
          var str = new String ("foo");
          str.append ("bar");
          str.length;
          => 6

System
------

Standard
     NGS JavaScript Interpreter VERSION

 -- Static Method on System: chdir (directory)
     Change the process' current working directory to DIRECTORY.  The function returns a boolean success status.

 -- Static Method on System: error (any[, ...])
     Convert arguments ANY... to string and print the resulting string to the standard error stream of the system.

 -- Static Method on System: exit (code)
     Terminate the program execution and return the value CODE to the operating system as the return value of the running program. Effectively the method performs C-code exit (CODE).

 -- Static Method on System: getcwd ()
     Get the current working directory of the process.  The function returns a strings presenting the directory or false if errors were encountered.

 -- Static Method on System: getenv (variable)
     Return the value of the environment variable VARIABLE.  The method returns the value as a string or undefined if the variable was not defined in the environment.

 -- Static Method on System: popen (command, mode)

 -- Static Method on System: print (any[, ...])
     Convert arguments ANY... to string and print the resulting string to the standard output stream of the system.

 -- Static Method on System: sleep (seconds)
     Stop the interpreter for SECONDS seconds.

 -- Static Method on System: strerror (errno)
     Return a string that describes the system error code ERRNO.

 -- Static Method on System: system (command)

 -- Static Method on System: usleep (micro_seconds)
     Stop the interpreter for MICRO_SECONDS micro seconds.

 -- Static Property of System: bits
     Return a value that describes the "bitness" of the underlying system. Possible values might be 16, 32, 64, or even 128.  Normally this is the size of a host system pointer in bits.

 -- Static Property of System: canonicalHost
     The canonical host name of the system where the interpreter was compiled.

          System.stdout.writeln (System.canonicalHost);
          -| powerpc-ibm-aix4.2.1.0

 -- Static Property of System: canonicalHostCPU
     The CPU part of the canonical host name.

          System.stdout.writeln (System.canonicalHostCPU);
          -| powerpc

 -- Static Property of System: canonicalHostVendor
     The Vendor part of the canonical host name.

          System.stdout.writeln (System.canonicalHostVendor);
          -| ibm

 -- Static Property of System: canonicalHostOS
     The OS part of the canonical host name.

          System.stdout.writeln (System.canonicalHostOS);
          -| aix4.2.1.0

 -- Static Property of System: errno
     The system's error number.  The error number can be converted to a string with the strerror() method of the System object.

          var fp = new File ("output.txt");
          if (!fp.open ("w"))
            System.error ("couldn't create output file `", fp, "': ",
                          System.strerror (System.errno), "\n");
          -| couldn't create output file `output.txt': Permission denied

 -- Static Property of System: lineBreakSequence
     The line break sequence that is used in the underlying system.  For example, the outputs from the following lines are identical:

          System.stdout.writeln ("Hello!");
          -| Hello!
          System.stdout.write ("Hello!" + System.lineBreakSequence);
          -| Hello!

 -- Static Property of System: stderr
     The system's standard error stream.  This is a normal JavaScript file and all methods of the File object can be called for it.

          System.stderr.writeln ("panic: must exit");
          System.exit (1);
          -| panic: must exit

 -- Static Property of System: stdin
     The system's standard input stream.

 -- Static Property of System: stdout
     The system's standard output stream.

VM
--

Standard
     NGS JavaScript Interpreter VERSION

 -- Static Method on VM: garbageCollect ()
     Perform a garbage collection for the virtual machine heap.  Normally, the garbage collection is triggered automatically, but the garbageCollect() method can be used to trigger the collection explicitly.

 -- Static Method on VM: stackTrace ([LIMIT])
     Print the contents of the virtual machine stack.  Optional argument LIMIT specifies how many stack frames are printed.  If no arguments are given, the whole virtual machine stack is printed.

          function recursive (n)
          {
            if (n > 5)
              VM.stackTrace ();
            else
              recursive (n + 1);
          }

          recursive (0);
          -|VM: stacktrace: stacksize=2048, used=78
          -|#0   recursive(): builtin 0
          -|#1   recursive(): null 1 6
          -|#2   recursive(): null 1 5
          -|#3   recursive(): null 1 4
          -|#4   recursive(): null 1 3
          -|#5   recursive(): null 1 2
          -|#6   recursive(): null 1 1
          -|#7   .global(): null 1 0

 -- Static Property of VM: dispatchMethod
     The name of the dispatch method, currently used in the virtual machine. The method returns a string that describes the method.  The possible return values are switch-basic, switch, and jumps.

 -- Static Property of VM: gcCount
     How many times the garbage collection has been performed for the heap.

 -- Static Property of VM: gcTrigger
     The garbage collection trigger.  When the virtual machine heap has allocated more than gcTrigger number of bytes of memory, the virtual machine will perform a garbage collection.

 -- Static Property of VM: heapAllocated
     The number of bytes of memory the system has allocated from the heap.

 -- Static Property of VM: heapFree
     The number of bytes of memory the heap freelist contains.

 -- Static Property of VM: heapSize
     The size of the heap in bytes.

 -- Static Property of VM: numConstants
     The number of constants defined in the virtual machine.

 -- Static Property of VM: numGlobals
     The number of global symbols defined in the virtual machine.  This value equals to the number of global variables and functions, defined in the system.

 -- Static Property of VM: stackSize
     The size of the virtual machine stack.

 -- Static Property of VM: stacktraceOnError
     A boolean flag that tells whether the virtual machine stack trace is printed if an error occurs in the program execution.

 -- Static Property of VM: verbose
     The verbosity level of the virtual machine.

 -- Static Property of VM: verboseStacktrace
     A boolean flag that tells whether the virtual machine prints the normal or verbose stacktrace.

 -- Static Property of VM: version
     The version string of the interpreter virtual machine.

 -- Static Property of VM: versionMajor
     The major version number of the virtual machine.

 -- Static Property of VM: versionMinor
     The minor version number of the virtual machine.

 -- Static Property of VM: versionPatch
     The patch level number of the virtual machine.

 -- Static Property of VM: warnUndef
     A boolean flag that tells whether the virtual machine should print a warning message if an undefined variable is used.

Extensions
==========

Curses
------

JS
--

 -- Constructor: JS ()

 -- Method on JS: compile (file, asm_file, bc_file)

 -- Method on JS: eval (string)

 -- Method on JS: evalFile (filename)

 -- Method on JS: evalJavaScriptFile (filename)

 -- Method on JS: executeByteCodeFile (filename)

 -- Method on JS: getVar (name)

 -- Method on JS: setVar (name, value)

 -- Property of JS: errorMessage

MD5
---

 -- Constructor: MD5 ()
     Create a new MD5 message digest object.

          var md5 = new MD5 ();

 -- Method on MD5: final ()
     Return the MD5 value of the data, set to the object with the update() method.  The method returns a 32 bytes long string that holds the MD5 value as a hexadecimal number.

          function print_md5 (str)
          {
            var md5 = new MD5 ();
            md5.update (str);
            System.print ("MD5 of \"", str, "\" is ",
                          md5.final (), ".\n");
          }
          print_md5 ("Hello, world!");
          -| MD5 of "Hello, world!" is 6CD3556DEB0DA54BCA060B4C39479839.

 -- Method on MD5: finalBinary ()
     Return the MD5 value of the data.  The method returns a 128 bits long MD5 value.

 -- Method on MD5: init ()
     Initalize the object to the initial state.  The method can be used to reset the object after some data has been set to it with the update() method.

 -- Method on MD5: update (str)
     Append data to the object.  The method can be called multiple times, so that the MD5 message digest can be counted one block at a time.

          function count_md5_for_file (stream)
          {
            var md5 = new MD5 ();

            while (!stream.eof ())
              {
                var data = stream.read (1024);
                md5.update (data);
              }

            return md5.final ();
          }

The js Program
**************

The js program is the JavaScript interpreter command.  It can be used to execute JavaScript and JavaScript byte-code files.  The progam can also be used to compile JavaScript files into the byte-code files.

Invoking The js Program
=======================

The js program is invoked as:

js OPTION... FILE [ARGUMENT...]

The js program processes the command line options and when the first non-option argument, or the option --file, is encountered, it is assumed to contain JavaScript or byte-code that should be evaluated.  The interpreter will pass all remaining arguments to the script throught the ARGS array.  The items in the array are strings containing the arguments ARGUMENT....  The first item of the array is always the name of the script FILE.

The options can be one or more of the following command line options:

-a
--annotate-assembler

     Annotate the created assembler listing with the original JavaScript source code.  The option can be used only with the --assembler option.

-c
--compile

     Compile JavaScript files to byte-code.  The generated byte-code is saved to file which name is created from the name of the input file by replacing the suffix .js with the suffix .jsc.  The compilation can be controlled with options --debug, --optimize, and --compiler-option.

-d TYPE
--dispatch=TYPE

     Use the byte-code instruction dispatch method TYPE.  The current implementation supports the following dispatch methods:

     switch-basic

          The basic switch-method using a big switch-case table to dispatch the instruction.  This method is available only if the interpreter has been configured with the option --with-all-dispatchers.

     switch

          An optimized version of the switch-method.  This method is supported on all environments.

     jumps

          The fastest dispatch method that uses the `computed goto' statement of the GNU C-compiler.  This method is available if the interpreter has been compiler with the GNU C-compiler.

     The default dispatch method, for environments that has the GNU C-compiler, is jumps.  For all other environments, the default method is switch.

-e CODE
--eval=CODE

     Evaluate JavaScript code CODE.

          $ js --eval='System.print ("Hello, world!\n");'
          -| Hello, world!

-E
--events

     Print the interpreter events to the standard error.

          $ js -E -c test.js
          [js: garbage collect]
          [js: garbage collect]
          [js: garbage collect]
          [js: garbage collect]

-f
--file

     Stop processing options and use the next argument as the name of the JavaScript (or byte-code) file.  All the remaining arguments are passed to the interpreter through the ARGS array.  The first item of the array will be the name of the script, i.e. the argument that follows the option --file.

          $ cat hello.js
          -| var i;
          -| for (i = 0; i < ARGS.length; i++)
          -|   System.print (i, ": ", ARGS[i], "\n");
          $ js --file hello.js a b c d
          -| 0: hello.js
          -| 1: a
          -| 2: b
          -| 3: c
          -| 4: d

     The option can also be used with the option --load to indicate the last file to load.  Also in that case, the remaining arguments will be passed to the script through the ARGS array.

-g
--debug

     Make the compiler to generate debugging information to the generated byte-code files.  This option can be used with the option --compile.

-h
--help

     Print a short help message that describes the options that can be given to the js program.

-l
--load

     Load multiple JavaScript and JavaScript byte-code files to the interpreter.  Normally, the first non-option argument is evaluated and all remaining arguments are passed to the script as arguments.  With the option --load, multiple files can be loaded the to the interpreter.  The loading can be stopped with option --file that specifies the last file to load.

     For example, if we have files a.js:

          function do_a ()
          {
            System.print ("do_a()\n");
          }

     b.js:

          function do_b ()
          {
            System.print ("do_b()\n");
          }

     and main.js:

          do_a ();
          do_b ();

     the whole application can be run as:

          $ js --load a.js b.js --file main.js ARGUMENTS...
          -| do_a()
          -| do_b()

-N
--no-compiler

     Do not define the compiler to the virtual machine.  This option makes the interpreter smaller, but the interpreter can only execute pre-compiled byte-code files.  The option disables the eval global method.

-O [LEVEL]
--optimize[=LEVEL]

     Set the compiler optimization level to LEVEL.  The compiler has three different optimization levels:

     0
          Do not optimize.

     1
          Perform all cheap optimizations which do not required heavy assembler instruction analyzing.

     2
          Perform all optimizations, supported by the compiler.

     The default optimization level is 1.

-r OPTION
--secure=OPTION

     Turn on virtual machine security option OPTION.  The following security options are available:

     file
          Disable insecure methods from the buit-in File object.

     system
          Disable insecure methods from the buit-in System object.

-s SIZE
--stack-size=SIZE

     Set the size of the virtual machine operand stack to SIZE.  The size of the virtual machine operand stack is set at the startup-time and it can't be enlarged dynamically at the runtime.

-S
--assembler

     Compile JavaScript files to JavaScript assembler.  The generated assembler listing is saved to file which name is created from the name of the input file by replacing the suffix .js with the suffix .jas.  The compilation can be controlled with options --optimize, and --compiler-option.

-t
--stacktrace

     Print a stack trace on error.  When an error occurs during the evaluation of a script, the virtual machine will halt and the js program terminates.  If the option --stacktrace was given to the interpreter, the virtual machine will print a stack trace that shows the call stack at the point of the error.

     The following listing showns an program that raises an error at the specified recursion level.

          function recursive (level)
          {
            if (level <= 0)
              error ("recursion limit exceeded");
            else
              recursive (level - 1);
          }

          recursive (5);

     If the program is executed without the --stacktrace option, the following result is shown:

          $ js hello.js
          js: evaluation of file `hello.js' failed:
          hello.js:6: recursion limit exceeded

     With the --stacktrace option, the js program will print the following error message:

          $ js --stacktrace hello.js
          -| VM: error: hello.js:6: recursion limit exceeded
          -| VM: stacktrace: stacksize=2048, used=44
          -| #0   recursive(): null 1 "recursion limit exceeded"
          -| #1   recursive(): null 1 0
          -| #2   recursive(): null 1 1
          -| #3   recursive(): null 1 2
          -| #4   recursive(): null 1 3
          -| #5   recursive(): null 1 4
          -| #6   .global(): null 1 5
          -| js: evaluation of file `hello.js' failed:
          -| hello.js:6: recursion limit exceeded

-v
--verbose

     Increase the verbosity of the interpreter.  The option can be given multiple times to increase the amount of messages the interpreter prints.

-V
--version

     Print the version number of the js program.

-W OPTION
--compiler-option=OPTION

     Set JavaScript compiler options according to the option specification OPTION.  The specification OPTION can be given in two forms. In the normal form, the option specifies a compiler option that should be set on.  If the specification OPTION starts with the prefix `no-', the specified option will be turn off.  The following option specifications are currently implemented:

     all
          match most of the compile time options

     pedantic
          match all compile time options.  This option generates as much warnings as possible.  It will also complain about some things that are allowed by the ECMAScript standard, but which are consired to show bad programming style, for example, missing semicolons.

     runtime
          match all runtime options

     shadow
          warn if a variable declaration shadows a parameter

     undefined
          runtime check for undefined global variables

     unused-argument
          warn about unused arguments

     unused-variable
          warn about unused local variables

     with-clobber
          warn if the with-lookup of a symbol is clobbered because the symbol is defined to be a local variable or a function argument

     missing-semicolon
          warn about missing semicolons that are fixed by the missing semicolon inserting during the compilation

     strict-ecma
          warn about things that are supported by this implementation, but are not allowed by the ECMAScript standard.  These features are:

            * line terminators in string and regular expression constants

     deprecated
          warn if deprecated features has been used in the source code

-x
--executable
     Add execute permissions to the generated byte-code files.  This option is useful on Linux environments where JavaScript byte-code files can be executed natively with the `binfmt_js' module.

          $ cat hello.js
          -| System.stdout.writeln ("Hello, world!");
          $ js -cx hello.js
          $ ./hello.jsc
          -| Hello, world!

Evaluating and Executing Code
=============================

Compiling JavaScript Code
=========================

The compilation of JavaScript code is carried out with the following command:

js [OPTIONS] -c FILE...

where FILE is a JavaScript source file to compile and OPTIONS specify additional compiler options.

In the simplest form, the compilation goes as follows:

     $ js -c hello.js

This example compiles file hello.js to byte-code file hello.jsc with the default compiler options.

Warning Messages
----------------

It is nice to get as many error messages as possible at the compilation time.  However, sometimes some error messages are false and it is annoying to see them every time you compile your project.  The option --compiler-option can be used to adjust the level of warning messages the compiler generates.

Normally we want to get all possible compiler time warnings.  They can be enable with the -Wall option.  To set the warnings individually, the following options can be given for the --compiler-option option.  The option names can be prefixed with string no- to turn them off instead of setting them.  For example, let's assume that we want to get as much warnings as possible, but we do not care about unused function arguments:

     $ js -Wall -Wno-unused-arguments -c hello.js

In this example, we turn on all warnings -Wall, but we turn off warnings about unused arguments -Wno-unused-arguments.

The js program knows the following warning options:

shadow
     Warn if a variable declaration shadows a parameter.  For example, when compiling file test.js containing code:

          function foo (a, b)
          {
            var a = 1;
            return a + b;
          }

     the following warning is generated:

          $ js -Wshadow -c test.js
          -| test.js:3: warning: declaration of `a' shadows a parameter

unused-argument
     Warn if an argument is not used in the function body.  For example, when compiling file test.js containing code:

          function foo (a, b)
          {
            return a + 5;
          }

     the following warning is generated:

          $ js -Wunused-argument -c test.js
          -| test.js:1: warning: unused argument `b'

unused-variable
     Warn if a local variable is not used in the function body.  For example, when compiling file test.js containing code:

          function foo (a, b)
          {
            var c;
            return a + b;
          }

     the following warning is generated:

          $ js -Wunused-variable -c test.js
          -| test.js:3: warning: unused variable `c'

with-clobber
     Warn if the with-lookup of a symbol is clobbered because the symbol is defined to be a local variable or a function argument.  For example, when compiling file test.js containing code:

          function foo (PI)
          {
            with (Math)
              System.print ("PI=", PI, "\n");
          }

     the following warning is generated:

          $ js -Wwith-clobber -c test.js
          -| test.js:4: warning: the with-lookup of symbol `PI' is
          -| clobbered by the argument definition

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.  For example, when compiling file test.js containing code:

          function foo ()
          {
            return 1
          }

          foo ()

     the following warnings are generated:

          $ js -Wmissing-semicolon -c test.js
          test.js:3: warning: missing semicolon
          test.js:6: warning: missing semicolon

strict-ecma
     warn about things that are supported by this implementation, but are not allowed by the ECMAScript standard.  For example, when compiling file test.js containing code:

          function foo ()
          {
            System.stdout.writeln ("Hello, world!
          ");
          }

     the following warning is generated:

          $ js -Wstrict-ecma -c test.js
          test.js:3: warning: ECMAScript don't allow line terminators in
          string constants

deprecated
     warn if deprecated features has been used in the source code.  For example, when compiling file test.js containing code:

          function foo ()
          {
            for (var i in arguments)
              System.stdout.writeln (i);
          }

     the following warning is generated:

          $ js -Wdeprecated -c test.js
          test.js:1: warning: the `arguments' property of Function instance
          is deprecated

Besides the compiler time checks, the virtual machine can also perform some checks at the runtime.  These checks can be set and unset with the -Wruntime option.

The following runtime warnings are supported:

undefined
     Warn if the value of an undefined global variable is used.  For example, when running file test.js containing code:

          foo = an_undefined_variable;

     the following warning is generated:

          $ js test.js
          -| VM: warning: using undefined global `an_undefined_variable'

Optimization
------------

Debugging Information
---------------------

As a default, the JavaScript compiler do not include symbolic debugging information to the generated byte-code files.  The debugging information can be generated by giving the compiler -g option.  The debugging information is also generated for the internal byte-code files that are created when the interpreter evaluates plain JavaScript source code.

In the current implementation, the debugging information contains only the names of the source files, and mappings from the virtual machine program counter offsets to the source file locations.  In the future, it will contain information about local variables and function arguments, so that the symbolic debugger can print their values.

The presence of the debugging information shows in the error messages the interpreter shows.  For example, let's consider the following JavaScript source code file test.js:

     function foo (a)
     {
       a += 1;
       if (a > 50)
         error ("a overflow");

       return 1;
     }

     foo (50);

When this file is compiled to the byte-code without debugging information, the following error message is raised:

     $ js -c test.js
     $ js test.jsc
     -| js: evaluation of file `test.jsc' failed:
     -| a overflow

If we recompile the file with the debugging information, we will get a more precise error message from the interpreter:

     $ js -g -c test.js
     $ js test.jsc
     -| js: evaluation of file `test.js' failed:
     -| test.js:5: a overflow

Now we see the exact source code location where the error occurred.

The debugging information can be removed from the byte-code files after the compilation with the jsdas program.

     $ jsdas --strip test.jsc
     test.jsc:
     jsdas: removing section 3
     $ js test.jsc
     js: evaluation of file `test.jsc' failed:
     a overflow

Assembler Listings
------------------

The JavaScript compiler can generate assembler listings from the JavaScript source files.  The assembler listings are generated just before the resulting byte-code data would be generated. So the resulting assembler listing is exactly the same that will be in the resulting byte-code data.  The assembler listing is generated with the --assembler option.  For example, if we have a source file hello.js with the following contents:

     function hello ()
     {
       System.stdout.writeln ("Hello, world!");
       return true;
     }

     hello ();

it can be compiled to assembler with command

     $ js -S hello.js

The command will save the assembler listing in file hello.jas:

     hello:
             load_arg        1
             add_2_i
             min_args        2
             const           "Hello, world!"
             const_i1
             load_global     System
             load_property   stdout
             call_method     writeln
             pop_n           4
             const_true
             return

     .global:
             const_i0
             const_null
             jsr             hello
             apop            2

The option --annotate-assembler can be used with the --assembler option.  It mixes the original source code to the generated assembler listing.  In this format, it is easy to see how different JavaScript constructs are compiled in the assembler.  Our example file can be compiled to the annotated assembler with the following command:

     $ js -a -S hello.js

The result listing is saved to file hello.jas:

     ; -*- asm -*-
     ; function hello ()

     hello:
     ; {
             load_arg        1
             add_2_i
             min_args        2
     ;   System.stdout.writeln ("Hello, world!");
             const           "Hello, world!"
             const_i1
             load_global     System
             load_property   stdout
             call_method     writeln
             pop_n           4
     ;   return true;
             const_true
             return
     ; }
     ;
     ; hello ();

     .global:
             const_i0
             const_null
             jsr             hello
             apop            2

The jsas Program
****************

The jsas program is a assembler for the JavaScript assembler. The program can be used to compile assembler files into byte-code.

Invoking The jsas Program
=========================

The jsas program is invoked as:

jsas OPTION... FILE...

The program reads the options and processes the assembler files FILE... according to the options. The options can be one of more of the following command line options:

-g
--debug

     Make the assembler to generate debugging information to the generated byte-code files.

-h
--help

     Print a short help message that describes the options that can be given to the jsas program.

-O
--optimize

     Optimize the assembler instructions.

-v
--verbose

     Turn on verbose diagnostic messages.  When this options is given, the jsas program tells what it is doing.

-V
--version

     Print the version number of the jsas program.

The jsdas Program
*****************

The jsdas program is a disassembler and a manipulator for the JavaScript byte-code files.  The program can be used to view, disassemble and manipulate the byte-code files.

Invoking The jsdas Program
==========================

The jsdas program is invoked as:

jsdas OPTION... FILE...

The program reads the options and processes the byte-code files FILE... according to the options.  The options can be one or more of the following command line options:

-c
--code

     Print the code section of the byte-code files.  This is the default action that is preformed if no options are given for the jsdas program.

-C
--constants

     Print the constants section of the byte-code file.

-d
--debug

     Print the debug section of the byte-code file.

-h
--help

     Print a short help message that describes the options that can be given to the jsdas program.

-i
--info

     Print the byte-code file information.

-l TYPE DATA
--link TYPE DATA

     Link a new section to the byte-code file.  The section's type is TYPE and its contents is read from file DATA.

-r TYPE
--remove TYPE

     Remove section of type TYPE from the byte-code files.

-s
--symtab

     Print the symbol table section of the byte-code file.

-S
--strip

     Remove the debug section from the byte-code files.

-V
--version

     Print the version number of the jsdas program.

Viewing Byte-Code Files
=======================

In this section we assume that we have a source file hello.js with the following contents:

     function main ()
     {
       System.print ("Hello, world!\n");
     }

     main ();

The file has been compiled to byte-code file hello.jsc with the following command:

     $ js -Wall -g -c hello.js

The option --info is used to view the contents of the byte-code file.  For example, our example file contains the following information:

     $ jsdas --info hello.jsc
     hello.jsc:

     * byte-code file information

       section 0: type=0 (code), length=34
       section 1: type=1 (constants), length=40
       section 2: type=2 (symtab), length=25
       section 3: type=3 (debug), length=40

We see that the byte-code file has four sections: code, constants, symtab and debug.  The listing shows also their lengths.  The sections are:

code
     the byte-code instructions of the file

constants
     the constant values of the file

symtab
     the symbol table

debug
     the debugging information

Next, we would like to see a assembler listing of the byte-code, defined in the code section of the file.  This can be viewed with the option --code that is the jsdas's default option (so no options for the following example).

     $ jsdas hello.jsc
     hello.jsc:

     * section `Code'

     main:
       0     load_arg        1
       2     add_2_i
       3     min_args        2
       5     const           "Hello, world!\n"
       10    const_i1
       11    load_global     System
       16    call_method     print
       21    pop_n           4
       23    const_undefined
       24    return

     .global:
       25    const_i0
       26    const_null
       27    jsr             main
       32    apop            2

The constants section holds the constant data the byte-code instructions need.  These constants are pushed to the stack with the const byte-code operand, or they are used to name a symbol in method invocation or in subroutine call.

The constant section can be viewed with the --constants option.

     $ jsdas --constants hello.jsc
     hello.jsc:

     * section `Constants'

       0:    "Hello, world!\n"
       1:    System
       2:    print
       3:    main

Our example file defines four constants.  A string Hello, world!\n and three symbols System, print, and main.

The debugging information holds line number information about the source file from which the file was compiled.  The debugging section can be viewed with the option --debug:

     $ jsdas --debug hello.jsc
     hello.jsc:

     * section `Debug'

       2     hello.js:2
       10    hello.js:3
       26    hello.js:6

The symbol table hold the information about the global symbols the byte-code file defines.  For each symbol, the symbol table has an offset that points to the appropriate location in the byte-code instruction stream.

The symbol table information can be viewed with the --symtab option:

     $ jsdas --symtab hello.jsc
     hello.jsc:

     * section `Symtab'

       main                                    0
       .global                                 25

Manipulating Byte-Code Files
============================

     $ jsdas --link 7001 hello.js hello.jsc
     hello.jsc:
     jsdas: linking 67 bytes of data to section 7001
     $ jsdas --info hello.jsc
     hello.jsc:

     * byte-code file information

       section 0: type=0 (code), length=34
       section 1: type=1 (constants), length=40
       section 2: type=2 (symtab), length=25
       section 3: type=3 (debug), length=40
       section 4: type=7001, length=67

     $ jsdas --remove 3 hello.jsc
     hello.jsc:
     jsdas: removing section 3
     $ jsdas --remove 7001 hello.jsc
     hello.jsc:
     jsdas: removing section 7001
     $ jsdas -i hello.jsc
     hello.jsc:

     * byte-code file information

       section 0: type=0 (code), length=34
       section 1: type=1 (constants), length=40
       section 2: type=2 (symtab), length=25

The `jswrap' Program
********************

The jswrap program is a tool that helps implementing C functions in JavaScript.

Invoking The jswrap Program
===========================

The jswrap program is invoked as:

jswrap OPTIONS... FILE

The jswrap program processes the command line options and according to them and the default values, it converts the input file FILE to the corresponding .h and .c files.  The options can be one of more of the following command line options:

-g
--debug

     Generate debugging information to the generated JavaScript byte-code.

-h FILE
--header FILE

     Generate the C header file to file FILE.  The default C header file name is constructed from the input file name by replacing the suffix .jsw with suffix .h.

-n
--no-error-handler

     Do not generate the default error handler to the generated C files.  If this option is specified, then the error handler must be defined in your code.

-o
--output FILE

     Generate the C output to file FILE.  The default output file name is constructed from the input file name by replacing the suffix .jsw with suffix .c.

-r
--reentrant

     Generate re-entrant C functions.  The option adds a `JSInterpPtr' argument to all C functions it generates.

-V
--version
     Print the version number of the jswrap program.

--help
     Print a short help message that describes the options that can be given to the jswrap program.

Definition File Format
======================

The definition file contains the function definitions and their implementation in JavaScript.  The function definitions are normal JavaScript function definitions but they are extended with the type information.  The type information is used to generate the C header files and the glue code that is used in the function call.  The definition file can also contain normal JavaScript comments.  The comments are ignored and they are not copied to the generated C header and implementation files.

The syntax of the function definition is:

     function [RETURN_TYPE] FUNCTION_NAME (ARGUMENT_TYPE... ARGUMENT[, ...])
     {
       JAVASCRIPT CODE IMPLEMENTING THE FUNCTION.
     }

Where:

return_type

     specifies the return type of the function.  If the return type specification is omitted, the function is a void function returning no value.

function_name

     is the name of the function.  The name must be a valid C identifier matching regular expression `^[A-Za-z_][A-Za-z_0-9]*'.

argument_type

     specifies the type of the argument, its passing type, and the life scope of the value of the argument.

argument

     is the name of the argument.  The name must be a valid C identifier.

The Type Specifiers
-------------------

The type specifiers specify the native C and JavaScript type that is used for the argument or for the return value.  The following type are supported:

cstring

     A '\0' terminated C-string.  In the C, this is presented as `char *'.  In the JavaScript, this is a normal string.

double

     A floating point number.  In the C, this is a `double' floating point number.

int

     An integer Number.  In the C, this is a `long' integer.

string

     An arbitrary data block.  In the C, this is presented as `unsigned char *, unsigned int' pair.  In the JavaScript, this is a normal string.  Note! Because the type's presentation in C is two types, this value can't be used as a return value of a function.

The following example shows how the types are converted to the corresponding C header file.  The input file types.jsw is as follows:

     function types (cstring vcstring, double vdouble, int vint,
                     string vstring)
     {
     }

The resulting C header file types.h contains the following definitions for the function types:

     void types (
             char *vcstring,
             double vdouble,
             long vint,
             unsigned char *vstring,
             unsigned int vstring_len
             );

The Pass-Type Specifiers
------------------------

The passing type specifiers specify how the argument is passed to the function.  The following specifies are supported:

in

     An input argument.  This is the default pass-type for arguments.

out

     An output argument.  In the JavaScript, the initial value of the argument is undefined.  When the control returns from the implementation of the function, the argument's current value is returned to the calling C function.

     In the C, the output and input-output arguments are presented as pointers to the variables, containing the values.

inout

     An input-output argument.

The following example shows show the output and input-output arguments are presented in the C header file.  The input file pass.jsw is as follows:

     function pass (out cstring vcstring, out double vdouble, inout int vint,
                    inout string vstring)
     {
     }

The resulting C header file pass.h contains the following definitions for the function pass:

     void pass (
             char **vcstring,
             double *vdouble,
             long *vint,
             unsigned char **vstring,
             unsigned int *vstring_len
             );

The Life Scope Specifiers
-------------------------

The life scope specifiers specify the liveness of the value, passed in an argument.  The following specifiers are supported:

static

     The argument points to static data that can't change while the execution is in the JavaScript code.  This means that the JavaScript can use the same data that is given to it; it don't have to make a private copy of the data.  The specifier can only be used with cstring and string types.

     The specifier don't have any affect for the generated C header file.

Re-Entrant Functions
====================

Calling the Functions from C
============================

Sample Project
==============

     function hello (cstring user)
     {
       System.stdout.writeln ("Hello, " + user + "!");
     }

     function int max_sum (int a, int b, int out sum)
     {
       sum = a + b;

       return a > b ? a : b;
     }

     $ jswrap sample.jsw

     /* This file is automatically generated from `hello.jsw' by jswrap. */

     #ifndef HELLO_H
     #define HELLO_H

     void hello (
             char *user
             );

     int max_sum (
             int a,
             int b,
             int *sum
             );

     #endif /* not HELLO_H */

     #include <js.h>
     #include "hello.h"

     JSInterpPtr jswrap_interp;

     int
     main (int argc, char *argv[])
     {
       int a, b, max, sum;

       jswrap_interp = js_create_interp (NULL);

       hello ("World");

       a = 5;
       b = 7;
       max = max_sum (a, b, &sum);
       printf ("%d + %d = %d, max(%d, %d) = %d\n", a, b, sum, a, b, max);

       return 0;
     }

JavaScript API
**************

Interpreter Handling
====================

 -- Function: const char * js_version ()
     Return a string that describes the JavaScript interpreter version number.  The returned string is in format "MAJOR.MINOR.PATCH", where MAJOR, MINOR, and PATCH are integer numbers.

 -- Function: void js_init_default_options (JSInterpOptions *OPTIONS)
     Initialize the interpreter options OPTIONS to the default values. These are the same values that are used in the interpreter creation, if the argument OPTIONS of js_create_interp() is NULL.

 -- Function: JSInterpPtr js_create_interp (JSInterpOptions *OPTIONS)
     Create a new JavaScript interpreter.  The function returns an interpreter handle that must be passed to all other interpreter API functions.  The argument OPTIONS specify additional options for the interpreter.  If the argument is NULL, the default values are used. If the interpreter creation fails -- due insufficient memory resources -- the function return value NULL.

 -- Function: void js_destroy_interp (JSInterpPtr INTERP)
     Destroy interpreter INTERP and free all resources the interpreter has allocated.  The handle INTERP must not be used after this function.

 -- Function: const char * js_error_message (JSInterpPtr INTERP)
     Return an error message of the latest error in interpreter INTERP.

 -- Function: void js_result (JSInterpPtr INTERP, JSType *RESULT_RETURN)
     Get the result of the latest evaluation or execution in interpreter INTERP.  The result is returned in RESULT_RETURN.  All data, returned in RESULT_RETURN, belongs to the interpreter.  The caller must not modify or changed it in any ways.

 -- Function: void js_set_var (JSInterpPtr INTERP, char *NAME, JSType *VALUE)

 -- Function: void js_get_var (JSInterpPtr INTERP, char *NAME, JSType *VALUE)

 -- Function: void js_get_options (JSInterpPtr INTERP, JSInterpOptions *OPTIONS)
     Get the options of interpreter INTERP to OPTIONS.

 -- Function: void js_set_options (JSInterpPtr INTERP, JSInterpOptions *OPTIONS)
     Modify the options of interpreter INTERP according to OPTIONS.

Evaluation and Compilation
==========================

 -- Function: int js_eval (JSInterpPtr INTERP, char *CODE)
     Evaluate JavaScript code CODE with interpreter INTERP.  The argument CODE is NUL-terminated a C-string holding the JavaScript code.  The function returns 1 if the operation was successful or 0 otherwise.  If the evaluation failed, the error message can be retrieved with function js_error_message().

 -- Function: int js_eval_data (JSInterpPtr INTERP, char *DATA, unsigned int DATALEN)
     Evaluate JavaScript code DATA, DATALEN with interpreter INTERP.

 -- Function: int js_eval_file (JSInterpPtr INTERP, char *FILENAME)
     Evaluate file FILENAME with interpreter INTERP.  The file FILENAME can contain JavaScript or byte-code.

 -- Function: int js_eval_javascript_file (JSInterpPtr INTERP, char *FILENAME)
     Evaluate JavaScript code file FILENAME with interpreter INTERP.

 -- Function: int js_execute_byte_code_file (JSInterpPtr INTERP, char *FILENAME)
     Execute a byte-code file FILENAME with interpreter INTERP.

 -- Function: int js_apply (JSInterpPtr INTERP, char *NAME, unsigned int ARGC, JSType *ARGV)
     Call function NAME with arguments ARGC, ARGV.  The return value of the function NAME can be retrieved with the js_result() function.

 -- Function: int js_compile (JSInterpPtr INTERP, char *INPUT_FILE, char *ASSEMBLER_FILE, char *BYTE_CODE_FILE)
     Compile JavaScript input file INPUT_FILE.  If the argument ASSEMBLER_FILE is not NULL, the generated assembler code is saved to the file, specified by the argument.  If the argument BYTE_CODE_FILE is not NULL, the generated byte-code data is svaed to the file, specified by the argument.

 -- Function: int js_compile_to_byte_code (JSInterpPtr INTERP, char *INPUT_FILE, unsigned char **BC_RETURN, unsigned int *BC_LEN_RETURN);
     Compile JavaScript file INPUT_FILE to byte-code and return the resulting byte-code data in BC_RETURN, BC_LEN_RETURN.  The returned byte-code data BC_RETURN belongs to the interpreter and it must be saved by the caller before any other JS functions is called.  If the data is not saved, its contents will be invalidated at the next garbage collection.

 -- Function: int js_compile_data_to_byte_code (JSInterpPtr INTERP, char *DATA, unsigned int DATALEN, unsigned char **BC_RETURN, unsigned int *BC_LEN_RETURN);

     Compile JavaScript code DATA, DATALEN to byte-code and return the resulting byte-code data in BC_RETURN, BC_LEN_RETURN.

 -- Function: int js_execute_byte_code (JSInterpPtr INTERP, unsigned char *BC, unsigned int BC_LEN);

     Execute byte-code data BC, BC_LEN.  The byte-code data is the contents of a byte-code file, or a copy of the data returned by the js_compile_to_byte_code() or js_compile_data_to_byte_code() functions.

     Note! You can't use the data from the js_compile_to_byte_code(), js_compile_data_to_byte_code() functions as an input for this function.  You must take a private copy of the data and pass that copy to the function:

          if (js_compile_to_byte_code (interp, file, &bc, &bclen))
            {
              char *bc_copy = xmalloc (bclen);
              memcpy (bc_copy, bc, bclen);
              js_execute_byte_code (interp, bc_copy, bclen);
              xfree (bc_copy);
            }

Type Handling
=============

 -- Function: void js_type_make_string (JSInterpPtr INTERP, JSType *TYPE, unsigned char *DATA, unsigned int LENGTH)
     Create a new string type from LENGTH bytes of data DATA. The result string is created to TYPE.

 -- Function: void js_type_make_array (JSInterpPtr INTERP, JSType *TYPE, unsigned int LENGTH)
     Create a new array type of length LENGTH.  The result array is created to TYPE.

Global Methods
==============

 -- Function: void js_create_global_method (JSInterpPtr INTERP, char *NAME, JSGlobalMethodProc PROC, void *CONTEXT, JSFreeProc CONTEXT_FREE_PROC)

Classes
=======

 -- Function: JSClassPtr js_class_create (void *CLASS_CONTEXT, JSFreeProc CLASS_CONTEXT_DESTRUCTOR, int NO_AUTO_DESTROY, JSConstructor CONSTRUCTOR)

     Create a new class with class context data CLASS_CONTEXT.  The context data is destroyed with CLASS_CONTEXT_DESTRUCTOR.  If the argument NO_AUTO_DESTROY is not 0, the JavaScript interpreter will not destroy the class when the interpreter is destroyed.  In that case, it is the caller's responsibility to call js_class_destroy() for the returned class handle, after the interpreter has been destroyed.  If the argument CONSTRUCTOR is not NULL, it is used to instantiate the class when a `new CLASS (ARGS[...]);' expression is evaluated in the JavaScript code.

 -- Function: void js_class_destroy (JSClassPtr CLS)
     Destroy class handle CLS.  The class handle must be created by the js_class_create() function, so that value 1 was given for the NO_AUTO_DESTROY argument.

 -- Function: JSVoidPtr js_class_context (JSClassPtr CLS)
     Return the class context of class CLS.  The returned value is the same that was given for the CLASS_CONTEXT argument in call of function js_class_create().

 -- Function: int js_class_define_method (JSClassPtr CLS, char *NAME, unsigned int FLAGS, JSMethodProc METHOD)
     Define a new method for the class CLS.  The name of the new method is NAME and its implementation is METHOD.  The argument FLAGS can have the following flags:

     JS_CF_STATIC
          The created method is a static method.

 -- Function: int js_class_define_property (JSClassPtr CLS, char *NAME, unsigned int FLAGS, JSPropertyProc PROPERTY)
     Define a new property for the class CLS.  The name of the property is NAME and its setter and getter function is PROPERTY.  The argument FLAGS can have the following flags:

     JS_CF_STATIC
          The property is a static property.

     JS_CF_IMMUTABLE
          The property is immutable.  An error to try to set the property.

 -- Function: int js_define_class (JSInterpPtr INTERP, JSClassPtr CLS, char *NAME)
     Define the class CLS to the interpreter INTERP with name NAME.  If the value 0 was given for the argument NO_AUTO_DESTROY of the function js_class_create(), the handle CLS must not be used after this call.

 -- Function: int js_instantiate_class (JSInterpPtr INTERP, JSClassPtr CLS, void *INSTANCE_CTX, JSFreeProc INSTANCE_CTX_DESTRUCTOR, JSType *RESULT_RETURN)

 -- Function: const JSClassPtr js_lookup_class (JSInterpPtr INTERP, char *NAME)
     Lookup the class context by name from the interpreter INTERP.

 -- Function: int js_isa (JSInterpPtr INTERP, JSType *OBJECT, JSClassPtr CLS, void **INSTANCE_CONTEXT_RETURN)

     Check if object OBJECT is an instance of class CLS.  The function returns a boolean success status.  If the argument INSTANCE_CONTEXT_RETURN is not NULL, it will be set to the instance context of object OBJECT.

Modules
=======

 -- Function: int js_define_module (JSInterpPtr INTERP, JSModuleInitProc INIT_PROC)

Virtual Machine
***************

Byte-Code File Format
=====================

File Header
-----------

magic
     An UInt32 number containing the JavaScript byte-code file magic. The value of the magic is 0xc0014a53.

nsects
     An UInt32 number containing the number of sections in this byte-code file.

Code Section
------------

Constants Section
-----------------

The constants section contains the constant values of the byte-code. The different constant types are stored as follows:

integer

     (UInt8)3, (Int32)VALUE

string

     (UInt8)4, (UInt32)LENGTH, LENGTH BYTES OF DATA

float

     (UInt8)5, (double)VALUE

symbol

     (UInt8)10, SYMBOL NAME, (UInt8)0

NaN

     (UInt8)13

regular expression

     (UInt8)100, (UInt8)FLAGS, (UInt32)LENGTH, LENGTH BYTES OF REGEXP SOURCE

     The item FLAGS holds the regular expression flags.  It is a combination of the following flags:

     0x01
          global match

     0x02
          ignore case

Symtab Section
--------------

Debug Section
-------------

Byte-Code Operands
==================

The virtual machine knows the following byte-code operands.  Each operand is identified by a 8 bit long unsigned integer number.  The first operand halt has code 0, the next operand done has code 1, and so on.  Some operand take arguments that are shown after the operand name in the following listing.  The meanings of the arguments are:

Int8
     The code of the operand is followed by a 8 bit long integer number argument.

Int16
     The code of the operand is followed by a 16 bit long integer number argument.

Int32
     The code of the operand is followed by a 32 bit long integer number argument.

Symbol
     The code of the operand is followed by a 32 bit long integer number argument.  The number is an offset to the constant section and the specified constant is a symbol that is the argument of the operand.

The notation

BEFORE => AFTER

desribes how the operand modifies the virtual machine stack. For example, the notation:

--- => undefined

means that the operand takes no items from the stack and it pushes value undefined to the stack.  The notation:

ANY ANY => boolean

means that the operand takes two items from the stack and it pushes a boolean result to the stack.

The virtual machine knows the following byte-code operands.

 -- Operand: halt   --- => ---
     Halt the virtual machine.  The program execution stops immediately and the virtual machine starts execute the following C-code:

          while (1)
            sleep (5);

     This "sleep forever" loop is implemented for debugging purposes.

 -- Operand: done   --- => ---
     The execution of the byte-code is finished and the control returns to the calling C-function.

 -- Operand: nop   --- => ---
     Do nothing; no operation.

 -- Operand: dup   any => any any
     Duplicate the item at the top of the stack.

 -- Operand: pop   any => ---
     Remove one item from the top of the stack.

 -- Operand: pop_n Int8   any ... any => ---
     Remove INT8 items from the top of the stack.

 -- Operand: apop Int8   any_n ... any_0 => any_0
     Remove INT8 items from the top of the stack, leaving the topmost item on the top of the stack.  This operand is used to remove arguments of a function call, leaving the function's return value to the top of the stack.

 -- Operand: swap   any_1 any_2 => any_2 any_1
     Swap the two topmost items in the stack.

 -- Operand: roll Int8   any_n ... any_1 any_0 => any_0 any_n ... any_1

 -- Operand: const Int32   --- => const
     Push a constant from the constant section to the stack.  The constant is specified by the value INT32.

 -- Operand: const_null   --- => null
     Push value null to the stack.

 -- Operand: const_true   --- => true
     Push value true to the stack.

 -- Operand: const_false   --- => false
     Push value false to the stack.

 -- Operand: const_undefined   --- => undefined
     Push value undefined to the stack.

 -- Operand: const_i0   --- => 0
     Push integer number 0 to the stack.

 -- Operand: const_i1   --- => 1
     Push integer number 1 to the stack.

 -- Operand: const_i2   --- => 2
     Push integer number 2 to the stack.

 -- Operand: const_i3   --- => 3
     Push integer number 3 to the stack.

 -- Operand: const_i Int32   --- => Int32
     Push integer number Int32 to the stack.

 -- Operand: load_global Symbol   --- => value
     Push the value of the global variable SYMBOL to the stack.  The operand will not lookup the variable SYMBOL from the with-chain.

 -- Operand: store_global Symbol   value => ---
     Store the topmost item of the stack to the global variable SYMBOL.

 -- Operand: load_arg Int8   --- => value
     Push the value of the argument INT8 to the stack.

 -- Operand: store_arg Int8   value => ---
     Store the topmost item of the stack to the argument INT8.

 -- Operand: load_local Int16   --- => value
     Push the value of the local variable INT16 to the stack.

 -- Operand: store_local Int16   value => ---
     Store the topmost item of the stack to the local variable INT16.

 -- Operand: load_property Symbol   object => value
     Push the value of the property SYMBOL of object OBJECT to the stack.

 -- Operand: store_property Symbol   object value => ---
     Save the value VALUE to the property SYMBOL of object OBJECT.

 -- Operand: load_array   object index => value
     Push the INDEX:th item of object OBJECT to the stack.

 -- Operand: store_array   value object index => ---
     Store the value VALUE to the INDEX:th position of object OBJECT.

 -- Operand: nth   any integer => item boolean
     Push the INTEGER:th item of object ANY to the stack.  Push a boolean success status that tells whether the object ANY did contain INTEGER:th item.

 -- Operand: cmp_eq   any1 any2 => boolean
     Compare the two objects ANY1, ANY2 for equality and push a boolean result code to the stack.

 -- Operand: cmp_ne   any any => boolean
     Compare the two objects ANY1, ANY2 for inequality and push a boolean result code to the stack.

 -- Operand: cmp_lt   any1 any2 => boolean
     Compare whether object ANY1 is smaller than object ANY2. Push a boolean result code to the stack.

 -- Operand: cmp_gt   any1 any2 => boolean
     Compare whether object ANY1 is greater than object ANY2. Push a boolean result code to the stack.

 -- Operand: cmp_le   any1 any2 => boolean
     Compare whether object ANY1 is smaller than, or equal to object ANY2.  Push a boolean result code to the stack.

 -- Operand: cmp_ge   any1 any2 => boolean
     Compare whether object ANY1 is greater than, or equal to object ANY2.  Push a boolean result code to the stack.

 -- Operand: cmp_seq   any1 any2 => boolean
     Compare the two objects ANY1, ANY2 for strict equality and push a boolean result code to the stack.

 -- Operand: cmp_sne   any any => boolean
     Compare the two objects ANY1, ANY2 for strict inequality and push a boolean result code to the stack.

 -- Operand: sub   any1 any2 => result
     Substract object ANY2 from object ANY1 and push the result to the stack.

 -- Operand: add   any1 any2 => result
     Add object ANY2 to object ANY1 and push the result to the stack.

 -- Operand: mul   any1 any2 => result
     Multiply object ANY1 with object ANY2 and push the result to the stack.

 -- Operand: div   any1 any2 => result
     Divide object ANY1 with object ANY2 and push the result to the stack.

 -- Operand: mod   integer1 integer2 => result
     Count object INTEGER1 modulo object INTEGER2 and push the result to the stack.

 -- Operand: neg   any => result
     Negate object ANY and push the result to the stack.

 -- Operand: and   any1 any2 => result
     Perform a bitwise and operation between objects ANY1 and ANY2 and push the result to the stack.

 -- Operand: not   any1 any2 => result
     Perform a bitwise not operation between objects ANY1 and ANY2 and push the result to the stack.

 -- Operand: or   any1 any2 => result
     Perform a bitwise or operation between objects ANY1 and ANY2 and push the result to the stack.

 -- Operand: xor   any1 any2 => result
     Perform a bitwise xor operation between objects ANY1 and ANY2 and push the result to the stack.

 -- Operand: shift_left   integer1 integer2 => integer
     Shift integer number INTEGER1 left INTEGER2 bits.  Push the result value to the stack.

 -- Operand: shift_right   integer1 integer2 => integer
     Shift integer number INTEGER1 right INTEGER2 bits.  Push the result value to the stack.

 -- Operand: shift_rright   integer1 integer2 => integer

 -- Operand: iffalse Int32   any => ---
     If the topmost item in the stack has boolean value `false', adjust the program counter with relative offset INT32.

 -- Operand: iftrue Int32   any => ---
     If the topmost item in the stack has boolean value `true', adjust the program counter with relative offset INT32.

 -- Operand: call_method Symbol   object => result
     Call method SYMBOL in the object OBJECT.  Push the result of the method call to the stack.

 -- Operand: jmp Int32   --- => ---
     Adjust program counter with relative offset INT32, e.g. jump to relative position PC + INT32.

 -- Operand: jsr   function => result
     Jump to subroutine FUNCTION and push the result of the subroutine call to the stack.  The operand will not process the with-chain.

 -- Operand: return   result => result
     Return from a subroutine with value RESULT.

 -- Operand: typeof   any => string
     Push the type name of object ANY to the stack.

 -- Operand: new   object => result object
     Create an instance of object OBJECT and call its constructor function.  Push the result from the constructor and the new instance to the stack.  The return value of the constructor is discarded.

 -- Operand: delete_property Symbol   object => undefined
     Delete property SYMBOL from object OBJECT.  Push value undefined to the stack.

 -- Operand: delete_array   object index => undefined
     Delete the INDEX:th property of object OBJECT.  Push value undefined to the stack.

 -- Operand: locals Int16   --- => undefined ... undefined
     Allocate INT16 local variables from the stack frame.  The operand locals must be called in the beginning of the function code.  The operand will push INT16 undefined values to the stack.  The values will be the place-holders for the local variables.

 -- Operand: min_args Int8   integer => ---
     If the number of the arguments for the function INTEGER is smaller than Int8, expand the stack frame so that the function gets Int8 arguments.  The created arguments will have value undefined.

 -- Operand: load_nth_arg   integer => argument
     Push the INTEGER'th argument of function to the top of the stack. The index INTEGER must be an integer number.

 -- Operand: with_push   object => ---
     Push object OBJECT to the function's with-lookup chain.

 -- Operand: with_pop Int8   --- => ---
     Pop INT8 objects from the function's with-lookup chain.

 -- Operand: try_push Int32   --- => ---
     Push a try-frame with a catch block offset INT32 to the virtual machine's try-chain.

 -- Operand: try_pop Int8   --- => ---
     Pop INT8 frames from the virtual machine's try-chain.

 -- Operand: throw   any => ---
     Throw an exception with value ANY.

 -- Operand: iffalse_b Int32   boolean => ---
     If the topmost item in the stack is false, adjust the program counter with relative offset INT32.  The operand assumes that the topmost item is a boolean value.

 -- Operand: iftrue_b Int32   boolean => ---
     If the topmost item in the stack is true, adjust the program counter with relative offset INT32.  The operand assumes that the topmost item is a boolean value.

 -- Operand: add_1_i   integer => integer
     Add integer number one to the top most item in the stack.  The operand assumes that the topmost item is an integer number.

 -- Operand: add_2_i   integer => integer
     Add integer number two to the top most item in the stack.  The operand assumes that the topmost item is an integer number.

 -- Operand: load_global_w Symbol   --- => value
     Push the value of the global variable SYMBOL to the stack.  The operand will lookup the property SYMBOL from the currently active with-chain.

 -- Operand: jsr_w Symbol   function => result
     Jump to subroutine FUNCTION and push the result of the subroutine call to the stack.  The operand will lookup the method SYMBOL from the currently active with-chain.  If the method is not found, the argument FUNCTION is used.

Stack Frame
===========

     JS_SP0  sp =>
     JS_SP1          local_var_N
     JS_SP2          ...
     JS_SP(N)        local_var_1
     JS_LOCAL(0)     local_var_0
                     return_addr
     JS_WITHPTR      with_ptr
     JS_ARGS_FIXP    args_fix
             fp =>   old_fp
     JS_ARG(0)       this
     JS_ARG(1)       arg_count
     JS_ARG(2)       argument_1
                     argument_2
                     ...
     JS_ARG(N)       argument_N
                     local_var_N
                     ...
                     local_var_0
                     args_fix
                     return_addr
                     with_ptr
                     old_fp
                     this
                     ...

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, 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;
     }

The following example shows how the compiler entry point can be called from JavaScript code.  The example code compiles a JavaScript source code file input.js into byte-code and stores the result to file ouput.jsc.

     try
       {
         JSC$compile_file ("input.js",
           		JSC$FLAG_OPTIMIZE_MASK | JSC$FLAG_WARN_MASK,
           		null, "output.jsc");
       }
     catch (e)
       {
         System.stdout.writeln ("compilation failed: " + e);
       }

GNU Library General Public License
**********************************

     [file lgpl.texinfo not included]