AT&T Home | AT&T Labs | Research
AT&T Labs, Inc. - Research

The Yoix® Scripting Language

Home | What's New | Grammar | Documentation | Download | License | YChart | YDAT | YWAIT | Byzgraf | FAQs
Compiler typedict
 
A Compiler is used to translate Yoix functions or separate Yoix scripts into bytecode (actually Java class files is more accurate) that can run on the Java Virtual Machine. A function is compiled into bytecode that is associated with the function and automatically used by the Yoix interpreter whenever it calls that function. A script is compiled into a special zip archive that usually is saved in a file that can be executed later by the Yoix interpreter, but only if the command line that starts the interpreter also includes an option that allows the execution of zipped archives. The Yoix interpreter builds and installs a Compiler in
VM.compiler
when it starts, so Yoix applications usually do not need to create their own Compiler. Yoix programs normally interact with a Compiler by reading or writing the following fields:
addtags An int that controls whether source file and line number information is included in code the compiler generates. A value of 0 (the default) means it will be omitted, while a non-zero value means source and line number information will be included.
alive An int that is 1 when the compiler is using a separate thread to compile functions that were queued using compileFunctionLater and 0 when that thread is not running. Storing 0 in alive kills the thread that is being used to compile queued functions and removes all functions from the queue.
compileFunction(Function func, ...) A Builtin that compiles one or more functions and returns an int that is the number of those functions that were successfully compiled. Trying to compile a function that is already compiled is harmless, but will be counted as a successful compilation in the return value.
compileFunctionLater(Function func, ...) A Builtin that queues one or more functions for compilation in a separate thread and returns an Array that is a snapshot of the queue.
compileScript(String path [, String dest] [, int savesource]) A Builtin that compiles the Yoix script referenced by path and if the compilation is successful it returns a zip archive, as a String, that can be written to a file where it can be executed later by the Yoix interpreter, and if the compilation fails it returns NULL. If the optional dest argument is supplied then compileScript will also try to write the zip archive to that file. If the optional savesource argument is non-zero the script source will also be saved in the zip archive.

Zip archives created by compileScript will be rejected by the interpreter if bit 1 in VM.zipped is not set, which currently is the default setting. VM.zipped is read-only and it can only be changed using the -z option, so right now you have to add -z2 (or -z3) to the command line that you use to start the interpreter whenever there's a compiled script that you want to execute. As usual the -? and --info options will give you more information about the command line options that the interpreter supports.

debug An int that is a collection of flags that can be used to debug the compiler. Setting bit 0 dumps the generated assembly language, setting bit 1 dumps the Java class file created from that assembly language, and setting bit 2 requests a detailed dump whenever there is a compiler or assembler error.
localcopymodel An int that should be 0 or 1 (the default) and is used to control how the compiler handles the local variables that it encounters when it compiles a function or script. The code generated by the compiler creates the same block data structures that the interpreter uses, so the compiler always has somewhere it can store local variables and when localcopymodel is 0 the block data structures are the only place they are stored.

Setting localcopymodel to 1 means local Yoix int and double variables will also be represented by primitive int and double variables in the assembly language that the compiler generates when it is asked to compile a function or script. Two places to store variables means the compiler has to recognize when the copies need to be synced and generate code that handles the update. The overhead rarely exceeds then benefit the compiler gets by being able to manipulate int and double variables directly using JVM instructions, which run significantly faster than they would otherwise.

Even though some of them may be implemented, assigning undocumented values to localcopymodel should be avoided.

priority An int that is the priority of the thread used to compile the functions queued by compileFunctionLater.
timestamp A read-only String that is the date associated with this version of the compiler.
version A read-only String that is the version assigned to this compiler.
Performance improvements from compilation range from nothing (e.g., in a function that calls Yoix builtins to do most of the work) to the ridiculous (e.g., 1000 times faster for a function with a loop that does nothing but increment a counter), with an improvement somewhere between 10% and 30% as fairly typical. Measuring the changes can be tricky because compiled functions (or scripts) are Java classes that have to be loaded and verified by the Java Virtual Machine before they can start running, so the first execution of a compiled Yoix function usually takes the most time. The JVM can also step in at any time and decide to translate the bytecode the Yoix compiler generated into native machine code and after it does you may notice another speed improvement.

Right now selective compilation of functions using compileFunction or compileFunctionLater is probably the best way to use the compiler. Heavily used functions that don't make excessive use of builtins, particularly ones that manipulate local int and double variables, may be good candidates for compilation. A mechanism that tells the interpreter to automatically compile heavily used functions probably is something that will be added in a future release.
 
 Example:   The first program,
import yoix.*.*;

Sum(int left, int right) = left + right;

VM.compiler.debug = 1;
VM.compiler.compileFunction(Sum);

printf("Sum(7, -3) = %d\n", Sum(7, -3));
prints
Sum(7, -3) = 4
on standard output and since we set the compiler's debug flag to 1 the assembly language generated by the compiler, which looks something like
public class att.research.yoix.$_CompiledClass1 {
    extern int att.research.yoix.YoixObject.getInt(int)
    extern static att.research.yoix.YoixObject
		att.research.yoix.YoixObject.newInt(int)

    public static att.research.yoix.YoixObject compiledMethod(
		att.research.yoix.YoixObject args,
		att.research.yoix.YoixStack stack,
		att.research.yoix.SimpleNode[] nodes,
		att.research.yoix.YoixObject[] objects
	) {

        int $N1
        push args
        push 2
        invoke att.research.yoix.YoixObject.getInt(int)
        store $N1
        int $N2
        push args
        push 1
        invoke att.research.yoix.YoixObject.getInt(int)
        store $N2
        push $N1
        push $N2
        add
        invoke att.research.yoix.YoixObject.newInt(int)
        return
    }
}
prints on standard error.

If we put the script

import yoix.*.*;

printf("hello, world\n");
if a file, say /tmp/script.yx, then
VM.compiler.compileScript("/tmp/script.yx", "/tmp/compiled.yx");
will compile /tmp/script.yx and store the result, which is a special zip archive, in /tmp/compiled.yx. Remember, when you want the interpreter to execute /tmp/compiled.yx you will need to use the -z2 or -z3 command line options, otherwise you will get an invalidscript error.
 
 See Also:  

 

Yoix is a registered trademark of AT&T Inc.