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

Class Assembler

Two Muq design goals are to provide secure, stable service to multiple users, and to allow unprivileges users to implement compilers for new languages. Together, these imply that the writer of a compiler must not be able to generate code that would crash the server or bypass security mechanisms.

To some extent, this is intractable: If the compiler generates unexpected code, and other people use it and run that code with their own privileges, their security will be compromised. To put it mildly. (See Ken Thompson's Turing Award acceptance speech, reprinted in Communications of the Association for Computing Machinery.)

However, we can at least guarantee that compilers can only generate valid executables that will not crash the server or, say, do fetches from non-existent offsets in the constant vector.

Class Assembler exists to provide this layer of security: It provides the only mechanism by which executable objects can be constructed in Muq, and ensures the basic validity of all such objects. It also provides a central pathway through which all code generation flows, in which a certain amount of language-independent optimization may be done.

Compilers create executables by creating an instance of Class Assembler, feeding it all the code for the proposed executable, then asking it to create the executable. The Assembler instance sanity-checks all input, preserves the state of the assembler internally out of reach of errant or malicious fingers, and on completion of assembly returns an executable guaranteed to be basically safe, if not necessarily sane.

Class Assembler adds the following properties to those of Class Plain:

$S.bytecodes:       Nonzero if code has been assembled since last reset.
$S.compileTime:    True iff fn should run at compiletime not runtime.
$S.fnLine:         Line# fn began on in src file (1st is 0). (Set by compiler.)
$S.fileName:       File containing source for function. (Set by compiler.)
$S.lineInFn:      Current line# in fn in source (1st is 0). (Set by compiler.)
$S.fnName:         Name of function currently being compiled. (Set by compiler.)
$S.neverInline?:   True iff user forbids compiling fn inline.
$S.nextLabel:      Label to be returned by next assembleLabelGet.
$S.pleaseInline?:  True iff user prefers compiling fn inline.
$S.saveDebugInfo: Non-nil to save debug support info on compiled functions.
$S.flavor:          NIL :thunk :promise or :mosGeneric.
$S.vars             Number of local variables in fn being compiled.

Note: For convenience, the $S properties are also available in the public (default) propdir.

The fnLine and lineInFn properties are both zero-based: The first line in a file is line zero, the first line in a function is line zero. However, users expect line numbers to begin at one, and text editors conventionally number them this way, so you should add one to either when displaying it.

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