diff --git a/README.md b/README.md index 9f15d86..1e83b2c 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,12 @@ A Mozilla Research project to specify and develop the extremely optimizable subset of JS targeted by compilers like Emscripten, Mandreel, and LLJS. -Discussion of the asm.js spec now takes place on Specifiction -[here](http://discourse.specifiction.org/c/asm-js). +~Discussion of the asm.js spec now takes place on Specifiction [here](http://discourse.specifiction.org/c/asm-js).~ -As of this update, this repo hosts the source for +The [spec repo](https://github.com/asm-js/spec) hosts the source for [the current asm.js Working Draft](http://asmjs.org/spec/latest/). -This repo also hosts JS source code which performs asm.js validation, however +This repo hosts JS source code which performs asm.js validation, however as of this update, this code is not up to date with the latest working draft and is not extensively tested. Patches to update it or fix bugs are welcome though. diff --git a/historic/def.pdf b/historic/def.pdf deleted file mode 100644 index ed67dd6..0000000 Binary files a/historic/def.pdf and /dev/null differ diff --git a/historic/def.tex b/historic/def.tex deleted file mode 100644 index a149d41..0000000 --- a/historic/def.tex +++ /dev/null @@ -1,1305 +0,0 @@ -\documentclass{article} - -\usepackage{mathpartir} -\usepackage{amssymb} -\usepackage{graphicx} -\RequirePackage{algorithm} -\RequirePackage[noend]{algpseudocode} - -\newcommand{\mod}{\mathrel{\mathrm{mod}}} -\newcommand{\imm}{\mathtt{imm}} -\newcommand{\mut}{\mathtt{mut}} -\newcommand{\funcall}[2]{{#1}\mathjs{(}{#2}\mathjs{)}} -\newcommand{\paren}[1]{\mathjs{(}{#1}\mathjs{)}} -\newcommand{\dom}{\mathit{dom}} -\newcommand{\funtype}{\mathit{fun}\mbox{-}\mathit{type}} -\newcommand{\vartype}{\mathit{var}\mbox{-}\mathit{type}} -\newcommand{\rettype}{\mathit{return}\mbox{-}\mathit{type}} -\newcommand{\imptype}{\mathit{import}\mbox{-}\mathit{type}} -\newcommand{\stdtype}{\mathit{std}\mbox{-}\mathit{type}} -\newcommand{\funty}[2]{({#1}) \rightarrow {#2}} -\newcommand{\seq}[1]{\overline{{#1}}} -\newcommand{\mathjs}[1]{\mbox{\texttt{{#1}}}} -\newcommand{\mathjssm}[1]{\mbox{\texttt{\scriptsize {#1}}}} -\newcommand{\return}[1]{\mathjs{return }{#1}\mathjs{;}} -\newcommand{\fun}[3]{\mathjs{function }{#1}\mathjs{(}{#2}\mathjs{) \char123{} }{#3}\mathjs{ \char125{}}} -\newcommand{\ternary}[3]{{#1}\,\mathjs{?}\,{#2}\,\mathjs{:}{#3}} -\newcommand{\afun}[2]{\mathjs{function}\mathjs{(}{#1}\mathjs{) \char123{} }{#2}\mathjs{ \char125{}}} -\newcommand{\var}[1]{\mathjs{var }{#1}\mathjs{;}} -\newcommand{\rel}[1]{\scriptsize [\textsc{#1}]} -\newcommand\defeq{\stackrel{\mbox{\tiny def}}{=}} -\newcommand{\while}[2]{\mathjs{while (}{#1}\mathjs{) }{#2}} -\newcommand{\dowhile}[2]{\mathjs{do }{#1}\mathjs{ while (}{#2}\mathjs{);}} -\newcommand{\for}[4]{\mathjs{for (}{#1}\mathjs{; }{#2}\mathjs{; }{#3}\mathjs{) }{#4}} -\newcommand{\switch}[2]{\mathjs{switch (}{#1}\mathjs{) \char123{} }{#2}\mathjs{ \char125{}}} -\newcommand{\switchdef}[3]{\mathjs{switch (}{#1}\mathjs{) \char123{} }{#2}\mathjs{ default:}\,{#3}\mathjs{ \char125{}}} -\newcommand{\brk}{\mathjs{break;}} -\newcommand{\brkl}[1]{\mathjs{break }{#1}\mathjs{;}} -\newcommand{\cont}{\mathjs{continue;}} -\newcommand{\contl}[1]{\mathjs{continue }{#1}\mathjs{;}} -\newcommand{\lab}[2]{{#1}\mathjs{:}\,{#2}} -\newcommand{\ifone}[2]{\mathjs{if (}{#1}\mathjs{) }{#2}} -\newcommand{\iftwo}[3]{\mathjs{if (}{#1}\mathjs{) }{#2}\mathjs{ else }{#3}} -\newcommand{\block}[1]{\mathjs{\char123{} }{#1}\mathjs{ \char125{}}} -\newcommand{\ok}{\mathrm{\mathbf{ok}}} -\newcommand{\rulebreak}{\vspace{.1in}\\} -\newcommand{\bit}{\mathtt{bit}} -\newcommand{\unsigned}{\mathtt{unsigned}} -\newcommand{\intsm}{\mathjssm{intish}} -\newcommand{\doublesm}{\mathjssm{doublish}} -\newcommand{\signed}{\mathtt{signed}} -\newcommand{\fixnum}{\mathtt{fixnum}} -\newcommand{\double}{\mathtt{double}} -\newcommand{\view}[2]{\mathtt{view}^{#1}_{#2}} -\newcommand{\extern}{\mathtt{extern}} -\newcommand{\unk}{\mathtt{unknown}} -\newcommand{\str}{\mathtt{string}} -\newcommand{\undef}{\mathtt{undefined}} -\newcommand{\void}{\mathtt{void}} -\newcommand{\nul}{\mathtt{null}} -\newcommand{\num}{\mathtt{number}} -\newcommand{\obj}{\mathtt{object}} -\newcommand{\mustret}{\mathsf{return}} -\newcommand{\seqcomp}{\mathrel{;}} -\newcommand{\getprop}[2]{{#1}\mathjs{[}{#2}\mathjs{]}} -\newcommand{\getpropsm}[2]{{#1}\mathjssm{[}{#2}\mathjssm{]}} -\newcommand{\longlong}[2]{\mathjs{[}{#1},{#2}\mathjs{]}} -\newcommand{\toint}[1]{\mathjs{\~{}\~{}}{#1}} -\newcommand{\todouble}[1]{\mathjs{+}{#1}} -\renewcommand{\int}{\mathtt{int}} -\newcommand{\dword}{\mathtt{bits64}} -\newcommand{\function}{\mathtt{function}} -\newcommand{\union}[2]{{#1}\mathrel{|}{#2}} -\newcommand{\boolish}{\mathtt{boolish}} -\newcommand{\floor}{\mathtt{floor}} -\newcommand{\imul}{\mathtt{imul}} -\newcommand{\intish}{\mathtt{intish}} -\newcommand{\doublish}{\mathtt{doublish}} -\newcommand{\Fun}{\mathtt{Function}} - -\newcommand{\progjudge}[1]{\vdash {#1}\ \ok} -\newcommand{\impjudge}[5]{{#1};{#2};{#3};{#4} \vdash {#5}\ \ok} -\newcommand{\iejudge}[4]{{#1};{#2} \vdash {#3} : {#4}} -\newcommand{\fnjudge}[2]{{#1} \vdash {#2}\ \ok} -\newcommand{\expjudge}[2]{{#1} \vdash {#2}\ \ok} -\newcommand{\stmtjudge}[5]{{#1};{#2} \vdash {#3} : {#4} / {#5}} -\newcommand{\exprjudge}[4]{{#1};{#2} \vdash {#3} : {#4}} -\newcommand{\stmtretjudge}[2]{\vdash {#1} \hookrightarrow {#2}} -\newcommand{\sjudge}[4]{{#1};{#2};{#3} \vdash {#4}\ \ok} - -\newcommand{\returns}{\mathit{returns}} -\newcommand{\breaks}{\mathit{breaks}} - -\begin{document} - -\title{\texttt{asm.js}: a High-Performance Subset of JavaScript} -\author{Dave Herman, Luke Wagner, and Alon Zakai} -\maketitle - -\section{Introduction} - -This document describes a formal definition of a subset of the -JavaScript programming language that can be used as a high-performance -compiler target language. This sublanguage or dialect, which we call -$\mathjs{asm.js}$, effectively describes a safe virtual machine for -memory-unsafe languages such as C and C++. - -Because $\mathjs{asm.js}$ is a proper subset of JavaScript, both -syntactically and semantically, the language is fully defined by a -static {\it validation} judgment, which yields a predicate that -determines whether a given JavaScript program is or is not in the -subset. No specification of a dynamic semantics is needed, since the -behavior of an $\mathjs{asm.js}$ program is simply defined by its -behavior as a JavaScript program. - -\subsection{Overview} - -The unit of compilation/validation of $\mathjs{asm.js}$ is the -$\mathjs{asm.js}$ {\it module}, which takes the form of a closed -JavaScript function beginning with the {\it prologue -directive}~\cite{es5}: -\[ -\mathjs{"use asm";} -\] -The presence of this directive serves two purposes. First, it allows -JavaScript engines that wish to provide specialized optimizations for -$\mathjs{asm.js}$ to efficiently recognize that the module should be -validated as an $\mathjs{asm.js}$, without the need for complex, -heuristic or concurrent recognition logic. (Since validation requires -a non-trivial traversal of the body of the module, it is likely too -expensive to speculatively validate {\it all} JavaScript code during -JIT compilation.) Second, by requiring the programmer or code -generator to state the intention explicitly that the code should be -recognized as $\mathjs{asm.js}$, it allows user agents to report -validation errors or performance faults to developer consoles. - -An $\mathjs{asm.js}$ module takes three optional parameters: a global -object, containing standard ECMAScript libraries, an {\it FFI object}, -containing custom imported functions and constants from external -JavaScript, and a JavaScript $\mathjs{ArrayBuffer}$ representing a -virtualized memory. The module can provide different views of the -buffer by using typed array wrappers imported from the environment: -\begin{verbatim} -function mod(global, foreign, buffer) { - "use asm"; - - var HEAP_I32 = new global.Int32Array(buffer); - var HEAP_F64 = new global.Float64Array(buffer); - // ... -} -\end{verbatim} - -The body of an $\mathjs{asm.js}$ module consists of any number of -function definitions, followed by an {\it export clause}: -\[ -\return{\mathjs{\char123{} foo:\,f, bar:\,g \char125{}}} -\] -If a module only exports a single function, it can do so directly, -without the object literal: -\[ -\return{\mathjs{foo}} -\] - -\subsection{Types} - -The $\mathjs{asm.js}$ language is statically typed: every function, -variable, and expression has a statically predictable type, according -to a type hierarchy covering a subset of JavaScript values (see -Section~\ref{sec:types}). Variables, parameters, and functions are -provided with an explicit type bound through a stylized use of -JavaScript coercions. This technique was pioneered by the Emscripten -compiler~\cite{emscripten}, and is now used by a number of compilers -that target JavaScript~\cite{mandreel,lljs}. - -For example, the following is a simple function from integers to -integers: -\begin{verbatim} -function id(x) { - x = x|0; - return x|0; -} -\end{verbatim} -Even though JavaScript provides only double-precision floating-point -numbers (doubles) in its data model, the $\mathjs{asm.js}$ type system -enforces that 32-bit integer values---a strict subset of -doubles---never overflow to larger doubles. This allows optimizing -compilers to represent these values as unboxed integers in 32-bit -registers or memory. - -Again following the practice established by Emscripten, it is possible -to do integer operations such as arithmetic and conditionals by means -of coercions: -\begin{verbatim} -function add1(x) { - x = x|0; - return ((x|0)+1)|0; -} -\end{verbatim} -While the JavaScript semantics dictates that the addition may overflow -to a larger number than a 32-bit integer, the outer coercion ensures -that the entire expression results in a 32-bit integer---the same -integer that would be produced by a signed, 32-bit addition in a -typical assembly language. The $\mathjs{asm.js}$ type system thus -ensures that integer operations can be efficiently compiled by -optimizing JavaScript engines to predictable machine instructions. - -\subsection{Validation, linking, and execution} - -The $\mathjs{asm.js}$ validator is defined as a static type system, -which can be performed by an optimizing JavaScript engine at the time -the module is parsed by the JavaScript engine. (If compilation time is -a concern, it can be delayed to runtime by hiding the source code in a -string and passed to $\mathjs{eval}$ or the $\mathjs{Function}$ -constructor.) During this phase, any static validation errors can be -reported to a developer console. - -After a $\mathjs{asm.js}$ module is compiled, its evaluation produces -a closure with an empty lexical environment. The module can be {\it -linked} by calling the function with an object representing the -imported environment and an optional buffer: -\begin{verbatim} -function mod(global, foreign, buffer) { - "use asm"; - // ... - return { f: foo, g: bar }; -} - -var foreign = { - consoleDotLog: console.log, - // ... -}; - -var buffer = new ArrayBuffer(0x100000); - -// link the module -var m = mod(window, foreign, buffer); -\end{verbatim} - -This linking phase may need to perform additional, dynamic -validation. In particular, dynamic validation can fail if, for -example, the $\mathjs{Int32Array}$ function passed in through the -environment does not turn out to construct a proper typed array -(thereby defeating typed array-based optimizations). - -The resulting module object provides access to the exported -$\mathjs{asm.js}$ functions, which have been fully validated (both -statically and dynamically) and optimized. - -\subsection{Notation conventions} - -The following notation conventions are used in this document. Optional -items in a grammar are presented in $[\mbox{square -brackets}]$. Sequences are presented with a $\seq{\mbox{horizontal -overbar}}$. The empty sequence is denoted by $\epsilon$. Integers and -integer literals are ranged over by the metavariables $i, j$; -these may also serve as sequence indices, in which case they are -natural numbers. Natural numbers are otherwise ranged over by the -metavariables $m, n$. Floating-point literals are ranged over by the -metavariable $r$. - -\subsection{Document outline} - -The remainder of this document proceeds as follows. -%% FIXME: outline - -\section{Abstract syntax} - -This section specifies the abstract syntax of $\mathjs{asm.js}$. The -grammar is presented with concrete syntax for conciseness and -readability, but should be read as describing the subset of abstract -syntax trees produced by a standard JavaScript parser. - -We make the following assumptions about canonicalization of -$\mathjs{asm.js}$ abstract syntax trees: -\begin{enumerate} -\item Parentheses are ignored in the AST. This allows parentheses to - be left out of any of the formal definitions of this spec. - -\item Empty statements ($\mathjs{;}$) are ignored in the AST. This - allows empty statements to be left out of any of the formal - definitions of this spec. - -\item The identifiers $\mathjs{arguments}$ and $\mathjs{eval}$ do not - appear in $\mathjs{asm.js}$ programs. If either of these identifiers - appears anywhere, static validation must fail. -\end{enumerate} - -In various places in this document, the meta-variables $f$, $g$, $x$, -$y$, and $z$ are used to range over JavaScript identifiers. - -We syntactically distinguish integer literals $i, j$ from -floating-point literals $r$. A floating-point literal is a JavaScript -number literal that contains a $\mathjs{.}$ character. - -\subsection{Modules} - -An $\mathjs{asm.js}$ module has the following syntax: -\[ -\begin{array}{rcl} -\mathit{mod} & ::= & \mathjs{function }[f]\mathjs{(}[\mathit{global}[, \mathit{foreign}[, \mathit{buffer}]]]\mathjs{) \char123{}} \\ - & & \qquad\mathjs{"use asm";} \\ - & & \qquad\seq{\var{\seq{x \mathjs{ = } \mathit{imp}}}} \\ - & & \qquad\seq{\mathit{fn}_g} \\ - & & \qquad\seq{\var{\seq{y \mathjs{ = } v}}} \\ - & & \qquad\mathit{exp} \\ - & & \mathjs{\char125{}} \\ -%% \fun{[m]}{[g[, e[, b]]]}{\mathjs{"use asm"; } \seq{\mathit{imp}_x}\ \seq{\mathit{fn}_f}\ \seq{\var{\seq{y \mathjs{ = } v}}}\ \mathit{exp}} -\end{array} -\] -The syntax consists of: -\begin{enumerate} -\item an optional module name; -\item up to three optional parameters; -\item a $\mathjs{"use asm";}$ prologue directive; -\item a sequence of import statements; -\item a sequence of function declarations; -\item a sequence of global variable declarations; and -\item a single export statement. -\end{enumerate} - -An import expression is either an FFI function binding, a -type-annotated (coerced) FFI value, or a heap view: -\[ -\begin{array}{rcl} -\mathit{imp} & ::= & \mathit{global}\mathjs{.}x \\ - & | & \mathit{global}\mathjs{.Math.}x \\ - & | & \mathjs{new }\funcall{\mathit{global}\mathjs{.}x}{\mathit{buffer}} \\ - & | & \mathit{foreign}\mathjs{.}x\mathjs{|0} \\ - & | & \mathjs{+}\mathit{foreign}\mathjs{.}x \\ - & | & \mathit{foreign}\mathjs{.}x \\ -\end{array} -\] -(We assume that the metavariables $\mathit{global}$, -$\mathit{foreign}$, and $\mathit{buffer}$ stand for fixed variables -names used consistently throughout the imports.) - -A function declaration has the following syntax: -\[ -\mathit{fn}_f ::= \fun{f}{\seq{x}}{\seq{x\mathjs{ = }\mathit{ann}_x\mathjs{;}}\ \seq{\var{\seq{y\mathjs{ = }v}}}\ \mathit{ss}} -\] -The syntax consists of type annotations for the parameters, a sequence -of local variable declarations, and a sequence of statements. - -Type annotations are either $\int$ or $\double$ coercions: -\[ -\mathit{ann}_x ::= x\mathjs{|0} ~|~ \todouble{x} -\] - -An export statement returns either a single function or an object -literal containing multiple functions: -\[ -\begin{array}{rcl} -\mathit{exp} & ::= & \return{f} \\ - & | & \return{\mathjs{\char123{} } \seq{x \mathjs{:} f} \mathjs{ \char125{}}} \\ -\end{array} -\] - -\subsection{Statements} - -The set of legal statements in $\mathjs{asm.js}$ includes blocks, -expression statements, conditionals, returns, loops, $\mathjs{switch}$ -blocks, $\mathjs{break}$ and $\mathjs{continue}$, and labeled -statements: -\[ -\begin{array}{rcl} -s & ::= & \block{\mathit{ss}} \\ - & | & e\mathjs{;} \\ - & | & \ifone{e}{s} \\ - & | & \iftwo{e}{s}{s} \\ - & | & \return{[\mathit{re}]} \\ - & | & \while{e}{s} \\ - & | & \dowhile{s}{e} \\ - & | & \for{[e]}{[e]}{[e]}{s} \\ - & | & \switch{e}{\seq{c}\ [d]} \\ - & | & \brkl{[\mathit{lab}]} \\ - & | & \contl{[\mathit{lab}]} \\ - & | & \lab{\mathit{lab}}{s} \\ -\\ -\mathit{ss} & ::= & \seq{s} \\ -\end{array} -\] - -Return arguments always have their type explicitly manifest: either a -$\signed$ or $\double$ coercion or a literal: -\[ -\mathit{re} ::= e\mathjs{|0} ~|~ \todouble{e} ~|~ v -\] - -The contents of $\mathjs{switch}$ blocks are restricted: in addition -to requiring the (optional) $\mathjs{default}$ clause to be the last -clause, each $\mathjs{case}$ clause is syntactically restricted to -contain only literal values: -\[ -\begin{array}{rcl} -c & ::= & \mathjs{case }v\mathjs{:}\,\mathit{ss} \\ -d & ::= & \mathjs{default:}\,\mathit{ss} \\ -\mathit{cd} & ::= & c ~|~ d \\ -\end{array} -\] - -\subsection{Expressions} - -Expressions include literals, lvalues, assignments, function calls, -unary expressions, binary expressions, and sequence expressions: -\[ -\begin{array}{rcl} -e & ::= & v \\ - & | & \mathit{lval} \\ - & | & \mathit{lval}\mathjs{ = }e \\ - & | & \funcall{f}{\seq{e}} \\ - & | & \mathit{unop}\ e \\ - & | & e\ \mathit{binop}\ e \\ - & | & \ternary{e}{e}{e} \\ - & | & \paren{\seq{e}} \\ -\\ -\mathit{unop} & ::= & \mathjs{+} ~|~ \mathjs{\~{}} ~|~ \mathjs{!} \\ -\\ -\mathit{binop} & ::= & \mathjs{+} ~|~ \mathjs{-} ~|~ \mathjs{*} ~|~ \mathjs{/} ~|~ \mathjs{\%} \\ - & | & \mathjs{|} ~|~ \mathjs{\&} ~|~ \mathjs{\^{}} ~|~ \mathjs{<<} ~|~ \mathjs{>>} ~|~ \mathjs{>>>} \\ - & | & \mathjs{<} ~|~ \mathjs{<=} ~|~ \mathjs{>} ~|~ \mathjs{>=} ~|~ \mathjs{!=} ~|~ \mathjs{==} \\ -\end{array} -\] - -Literals are either doubles or integers: -\[ -v ::= r ~|~ i -\] - -Lvalues are either variables or typed array dereference -expressions. The latter requires a mask to force the byte offset into -a valid range and a shift to convert the offset into a proper index -for the size of the typed array. -\[ -\mathit{lval} ::= x ~|~ \getprop{x}{i} ~|~ \getprop{x}{e\mathjs{ \& }\mathit{mask}} ~|~ \getprop{x}{\paren{e\mathjs{ \& }\mathit{mask}}\mathjs{ >> }i} -\] -The $\mathit{mask}$ is a non-negative integer $2^k - 1$ where $k \in -[3, 31]$. The same $\mathit{mask}$ must be used consistently -throughout the program. - -\section{Types} -\label{sec:types} - -The $\mathjs{asm.js}$ validator relies on a static type system that -classifies and constraints the syntax beyond the grammar. - -\subsection{Expression types} - -The set of {\it expression types} classifies the results of expression -evaluation and constrains the allowable values of variables. -\[ -\begin{array}{rcl} -\sigma, \tau & ::= & \fixnum ~|~ \signed ~|~ \unsigned ~|~ \int ~|~ \intish \\ - & | & \double ~|~ \doublish ~|~ \extern ~|~ \unk ~|~ \void \\ -%% \sigma, \tau & ::= & \double ~|~ \signed ~|~ \unsigned ~|~ \fixnum ~|~ \extern \\ -%% & | & \bit ~|~ \int ~|~ \boolish ~|~ \intish ~|~ \void ~|~ \unk \\ -\end{array} -\] - -These types are arranged in a subtyping hierarchy, defined by: -\[ -\begin{array}{rcl} -\fixnum & <: & \signed, \unsigned \\ -\signed, \unsigned & <: & \int, \extern \\ -\double & <: & \extern, \doublish \\ -\unk & <: & \intish, \doublish \\ -\int & <: & \intish \\ -\end{array} -\] - -Figure~\ref{fig:subtypes} depicts this subtyping hierarchy -visually. Note that some types are presented in white boxes and others -in gray boxes. The white boxes represent types that may escape into -external JavaScript; the gray types are internal to the -$\mathjs{asm.js}$ module and cannot escape. This allows an optimizing -implementation to use unboxed representations that would otherwise be -illegal. What follows is an explanation of each type. - -\begin{figure}[tb] -\centering -\includegraphics[scale=0.5]{subtypes} -\caption{The hierarchy of expression types.} -\label{fig:subtypes} -\end{figure} - -\subsubsection*{The $\extern$ type} - -This abstract type represents the root of all types that can escape -back into ordinary JavaScript. Any type that is a subtype of $\extern$ -must carry enough information in its internal representation in an -optimizing virtual machine to faithfully convert back into a dynamic -JavaScript value. - -\subsubsection*{The $\double$ type} - -This is the type of double-precision floating-point values. An -optimizing engine can represent these as unboxed 64-bit floats. If -they escape into external JavaScript they must of course be wrapped -back up as JavaScript values according to the JavaScript engine's -value representation. - -\subsubsection*{The $\signed$ and $\unsigned$ types} - -These are the types of signed and unsigned 32-bit integers, -respectively. For an optimizing engine, their representation can be -the same: an unboxed 32-bit integer. If a value escapes into external -JavaScript, the sign is used to determine which JavaScript value it -represents. For example, the bit pattern $\mathjs{0xffffffff}$ -represents either the JavaScript value $\mathjs{-1}$ or -$\mathjs{4294967295}$, depending on the signedness of the type. - -\subsubsection*{The $\fixnum$ type} - -This type represents integers in the range $[0, 2^{31})$, which are -both valid signed and unsigned integers. Literals in this range are -given the type $\fixnum$ rather than $\signed$ or $\unsigned$, since -either way they have the same representation as an unboxed 32-bit -integer. - -\subsubsection*{The $\int$ type} - -This is the type of 32-bit integers whose sign is not known. Again, -optimizing engines can represent them as unboxed 32-bit integers. But -because the sign is not known, they cannot be allowed to escape to -external JavaScript, as it is impossible to determine exactly which -JavaScript value they represent. While this might not seem like a very -useful type, the JavaScript bitwise coercions can be used to force an -$\int$ value back to $\signed$ or $\unsigned$ without any loss of -data. - -The conditional operators also produce the $\int$ type, even though, -according to the JavaScript semantics, they produce boolean -values. Since boolean values convert to the integer values -$\mathjs{0}$ and $\mathjs{1}$, it is sound to represent the boolean -values in an optimizing engine as integers, even while allowing them -to be stored in integer values and passed to integer -arithmetic. Similarly, integer values can be treated as ``boolish'' in -JavaScript when used in conditional contexts, so it is safe to store -boolean values as unboxed integers even when being used in the test -expression of an $\mathjs{if}$ statement and the like. - -\subsubsection*{The $\intish$ type} - -The JavaScript arithmetic operations can be performed on 32-bit -integer values, but their results may produce non-integer values. For -example, addition and subtraction can overflow to large numbers that -exceed the 32-bit integer range, and integer division can produce a -non-integer value. However, if the result is coerced back to an -integer, the resulting arithmetic operation behaves identically to the -typical corresponding machine operation (i.e., integer addition, -subtraction, or division). The $\intish$ type represents the result of -a JavaScript integer artihmetic operation that must be coerced back to -integer with an explicit coercion. Because this type can only be used -as an argument to a coercion (or silently ignored in an expression -statement), $\mathjs{asm.js}$ integer arithmetic can always be -implemented in an optimizing engine by the machine integer artithmetic -operations. - -The one arithmetic operation that does not quite fit into this story -is multiplication. Multiplying two large integers can results in a -large enough double that some lower bits of precision are lost, so -that coercing the result back to integer does {\it not} behave -identically to the machine operation. The use of the proposed ES6 -$\mathjs{Math.imul}$ function~\cite{imul} as an FFI function is -recommended as the proper means of implementing integer -multiplication. - -In short: - -\begin{quote} -The $\intish$ type represents the result of integer operations that -must be dropped or immediately coerced via $\mathit{ToInt32}$ or -$\mathit{ToUint32}$. -\end{quote} - -\subsubsection*{The $\doublish$ type} - -Similarly, the $\doublish$ type represents operations that are -expected to produce a $\double$ but may produce additional junk that -must be coerced back to a number via $\mathit{ToNumber}$. In -particular, reading from the typed array may produce -$\mathjs{undefined}$, and calling FFI functions may produce an -arbitrary JavaScript value. Thus: - -\begin{quote} -The $\doublish$ type represents the result of numeric operations that -must be dropped or immediately coerced via $\mathit{ToNumber}$. -\end{quote} - -\subsubsection*{The $\unk$ type} - -Calling an external JavaScript function through the FFI results in an -arbitrary JavaScript value. Because $\mathjs{asm.js}$ is designed to -avoid dealing with general values, the result must be coerced to one -of the other types before it can be used. The $\unk$ type represents -one of these result values before being coerced to an integer or -double. - -\subsubsection*{The $\void$ type} - -A function that returns $\mathjs{undefined}$ is considered to have the -$\void$ result type. The $\mathjs{undefined}$ value is not actually a -first-class value in $\mathjs{asm.js}$. It can only be ignored via an -expression statement. This avoids having to represent it at all as -data. - -\subsection{Global types} - -Validation tracks the types not only of expressions and local -variables but also global variables, FFI imports, and functions. In -addition to variables of expression type, globals may also be typed -array views on the module's buffer, imported FFI constants and -functions, and functions defined in the $\mathjs{asm.js}$ module. -\[ -\gamma ::= \tau ~|~ \view{n}{\tau} ~|~ (\funty{\seq{\sigma}}{\tau}) \land \cdots \land (\funty{\seq{\sigma'}}{\tau'}) ~|~ \Fun -\] - -The type of a typed array tracks the number of bytes per element and -the elements' value type ($\intish$ or $\doublish$). A function type -may be overloaded to allow different parameter types, potentially -providing different result types for each overloading. - -\subsection{Operator types} - -Every operator, unary or binary, has an overloaded function type. -This overloading corresponds to the different machine operations used -in an optimizing engine to implement the various cases. Whereas -JavaScript generally needs to choose the behavior of operators -dynamically, $\mathjs{asm.js}$ makes it possible to resolve the -overloaded operators statically based on the types of the operands. - -The types of the arithmetic operators are as follows: -\[ -\begin{array}{rcc@{\ }l} -\mathjs{+} & : & & \funty{\double, \double}{\double} \\ -% & & \land & \funty{\int, \int}{\intish} \\ -\mathjs{-} & : & & \funty{\doublish, \doublish}{\double} \\ -% & & \land & \funty{\int, \int}{\intish} \\ -\mathjs{*} & : & & \funty{\doublish, \doublish}{\double} \\ -\mathjs{/} & : & & \funty{\doublish, \doublish}{\double} \\ - & & \land & \funty{\signed, \signed}{\intish} \\ - & & \land & \funty{\unsigned, \unsigned}{\intish} \\ -\mathjs{\%} & : & & \funty{\doublish, \doublish}{\double} \\ - & & \land & \funty{\signed, \signed}{\int} \\ - & & \land & \funty{\unsigned, \unsigned}{\int} \\ -\end{array} -\] -%% Note that some operations produce the type $\intish$, indicating that -%% their result must be immediately coerced back to an integer. Note also -%% that some operations accept $\doublish$ arguments, because they coerce -%% them immediately with $\mathit{ToNumber}$. (This is not the case for -%% the binary $\mathjs{+}$ operator, which therefore requires its -%% argument to be a true $\double$.) -The type of addition and subtraction only deals with floating-point -arithmetic; for integer addition and subtraction see -Section~\ref{sec:exprjudge}. Similarly, the $\mathjs{*}$ operator -provides only floating-point multiplication; integer multiplication -can be implemented via the $\imul$ function. The $\mathjs{/}$ operator -does provide both floating-point and integer division; for the latter -it produces the type $\intish$, which requires a coercion via the -bitwise operators to produce the proper integer result. The -$\mathjs{\%}$ operator works as either a floating-point or integer -operator and produces the correct result without any need for a -coercion. - -The bitwise operators are one of only two places in the language that -can consume an $\intish$ expression. Every one of these operators can -be composed with the arithmetic operators to produce the correct -behavior of integer arithmetic. -\[ -\begin{array}{rcc@{\ }l} -\mathjs{|}, \mathjs{\&}, \mathjs{\^{}}, \mathjs{<<}, \mathjs{>>} - & : & & \funty{\intish, \intish}{\signed} \\ -\mathjs{>>>} & : & & \funty{\intish, \intish}{\unsigned} \\ -\end{array} -\] - -The conditional operators rely on the sign of their input and produce -a boolean result: -\[ -\begin{array}{rcc@{\ }l} -\mathjs{<}, \mathjs{<=}, \mathjs{>}, \mathjs{>=}, \mathjs{==}, \mathjs{!=} - & : & & \funty{\signed, \signed}{\int} \\ - & & \land & \funty{\unsigned, \unsigned}{\int} \\ - & & \land & \funty{\double, \double}{\int} \\ -\end{array} -\] - -Finally, the unary operators have function types as well; unary -operations can also serve as coercions: the $\mathjs{+}$ operator -converts integers and the results of typed array reads and FFI calls -to $\double$, and the $\mathjs{\~{}}$ operator can be used to coerce -$\intish$ expressions, similar to the two-argument bitwise operators. -\[ -\begin{array}{rcc@{\ }l} -\mathjs{+} & : & & \funty{\signed}{\double} \\ - & & \land & \funty{\unsigned}{\double} \\ - & & \land & \funty{\doublish}{\double} \\ -\mathjs{-} & : & & \funty{\int}{\intish} \\ - & & \land & \funty{\doublish}{\double} \\ -\mathjs{\~{}} & : & & \funty{\intish}{\signed} \\ -\end{array} -\] - -\section{Validation} - -This section describes the $\mathjs{asm.js}$ validation process, which -is essentially a static type system. - -\subsection{Standard libraries} - -The JavaScript $\mathjs{Math}$ API is recognized as a typed standard -library; most of its functions are allowed as imports with the same -name and are given appropriate function types. These functions must be -passed into the import environment under their respective names (e.g., -$\mathjs{Math.sin}$ under the name $g\mathjs{.Math.sin}$). Building in -support for these standard functions allows optimizing engines to -build special support for them---particularly the $\imul$ operation, -which can be implemented with hardware multiplication instructions. -\[ -\begin{array}{rcl} -M(\mathtt{acos}), M(\mathtt{asin}), M(\mathtt{atan}) & = & \funty{\doublish}{\double} \\ -M(\mathtt{cos}), M(\mathtt{sin}), M(\mathtt{tan}) & = & \funty{\doublish}{\double} \\ -M(\mathtt{ceil}), M(\mathtt{floor}) & = & \funty{\doublish}{\double} \\ -M(\mathtt{exp}), M(\mathtt{log}), M(\mathtt{sqrt}) & = & \funty{\doublish}{\double} \\ -M(\mathtt{abs}) & = & \funty{\signed}{\unsigned} \\ - & \land & \funty{\doublish}{\double} \\ -M(\mathtt{atan2}), M(\mathtt{pow}) & = & \funty{\doublish, \doublish}{\double} \\ -M(\imul) & = & \funty{\int, \int}{\signed} \\ -M(\mathtt{random}) & = & \funty{}{\double} \\ -M(\mathtt{E}) & = & \double \\ -M(\mathtt{LN10}), M(\mathtt{LN2}), M(\mathtt{LOG2E}), M(\mathtt{LOG10E}) & = & \double \\ -M(\mathtt{PI}) & = & \double \\ -M(\mathtt{SQRT1\_2}), M(\mathtt{SQRT2}) & = & \double \\ -\end{array} -\] - -\subsection{View types} - -The typed array constructors are also recognized as imports in the -import environment, each under its standard name. Calling the various -typed arrays constructors on the buffer produces typed array views of -various types. -\[ -\begin{array}{rcl} -V(\mathtt{Uint8Array}), V(\mathtt{Int8Array}) & = & \view{1}{\intsm} \\ -V(\mathtt{Uint16Array}), V(\mathtt{Int16Array}) & = & \view{2}{\intsm} \\ -V(\mathtt{Uint32Array}), V(\mathtt{Int32Array}) & = & \view{4}{\intsm} \\ -V(\mathtt{Float32Array}) & = & \view{4}{\doublesm} \\ -V(\mathtt{Float64Array}) & = & \view{8}{\doublesm} \\ -\end{array} -\] - -\subsection{Global constants} - -\[ -\begin{array}{rcl} -G(\mathtt{Infinity}), G(\mathtt{NaN}) & = & \double \\ -\end{array} -\] - -\subsection{Annotations} - -Type annotations are provided in the form of explicit -coercions. Variables in $\mathjs{asm.js}$ are always taken to have the -type $\double$ or $\int$, never $\signed$ or $\unsigned$. This is -because they are intended to be representable as unboxed 32-bit words -in memory or registers, which are agnostic about what sign to -interpret the bits with. - -\[ -\begin{array}{rcl} -\vartype(\todouble{x}), \vartype(r) & = & \double \\ -\vartype(x\mathjs{|0}), \vartype(i) & = & \int \mbox{ $(-2^{31} \leq i < 2^{32})$} -\end{array} -\] - -Function return types are determined by explicit coercions in their -return statements. Function return types are always explicit about -their sign so that they can be exported to external JavaScript. - -\[ -\begin{array}{rcl} -\rettype(\todouble{e}), \rettype(r) & = & \double \\ -\rettype(e\mathjs{|0}), \rettype(i) & = & \signed \mbox{ $(-2^{31} \leq i < 2^{31})$} \\ -\rettype(\epsilon) & = & \void \\ -\end{array} -\] - -The type of a function can be extracted by looking at its parameter -annotations and return statements. - -\[ -\begin{array}{l} -\funtype(\fun{f}{\seq{x}}{\seq{x\mathjs{ = }\mathit{ann}_x\mathjs{;}}\ \seq{\var{\seq{y\mathjs{ = }v}}}\ \mathit{ss}\ \return{[\mathit{re}]}}) = \funty{\seq{\sigma}}{\tau} \\ -\qquad \mbox{where } \forall i . \vartype(\mathit{ann}_{x_i}) = \sigma_i \\ -\qquad \mbox{and } \rettype([\mathit{re}]) = \tau \\ -\funtype(\fun{f}{\seq{x}}{\seq{x\mathjs{ = }\mathit{ann}_x\mathjs{;}}\ \seq{\var{\seq{y\mathjs{ = }v}}}\ \mathit{ss}\ s}) = \funty{\seq{\sigma}}{\void} \\ -\qquad \mbox{where } \forall i . \vartype(\mathit{ann}_{x_i}) = \sigma_i \\ -\qquad \mbox{and } s \not= \return{[\mathit{re}]} \\ -\funtype(\fun{f}{\seq{x}}{\seq{x\mathjs{ = }\mathit{ann}_x\mathjs{;}}\ \seq{\var{\seq{y\mathjs{ = }v}}}\ \epsilon}) = \funty{\seq{\sigma}}{\void} \\ -\qquad \mbox{where } \forall i . \vartype(\mathit{ann}_{x_i}) = \sigma_i \\ -\end{array} -\] - -The types of import expressions are determined by the standard library -metafunctions $G$, $M$, and $V$ or by their coercion. A foreign import -with no coercion is assumed to be a function. - -\[ -\begin{array}{l} -\imptype(\mathit{global}\mathjs{.}x) = G(x) \\ -\imptype(\mathit{global}\mathjs{.Math.}x) = M(x) \\ -\imptype(\mathjs{new }\funcall{\mathit{global}\mathjs{.}x}{\mathit{buffer}}) = V(y) \\ -\imptype(\mathit{foreign}\mathjs{.}x\mathjs{|0}) = \signed \\ -\imptype(\mathjs{+}\mathit{foreign}\mathjs{.}x) = \double \\ -\imptype(\mathit{foreign}\mathjs{.}x) = \Fun \\ -\end{array} -\] - -\subsection{Module validation} - -Module validation takes an $\mathjs{asm.js}$ module and constructs a -{\it global environment} $\Delta$, which is used to track the types of -all globals: imports, buffer views, global variables, and functions. -\[ -\begin{array}{rcl} -\mu & ::= & \mut ~|~ \imm \\ -\Delta & ::= & \{ \seq{x : \mu\,\gamma} \} \\ -\end{array} -\] -Validation then uses this environment to check the imports, exports, -and function definitions. - -\newsavebox{\modjudge} -\begin{lrbox}{\modjudge} -\begin{minipage}[t]{3in} -\vspace{-.25in} -\[ -\begin{array}{rll} - & \mathjs{function }[f]\mathjs{(}[\mathit{global}[, \mathit{foreign}[, \mathit{buffer}]]]\mathjs{) \char123{}} \\ - & \qquad\mathjs{"use asm";} \\ - & \qquad\seq{\var{\seq{x \mathjs{ = } \mathit{imp}}}} \\ -\vdash & \qquad\seq{\mathit{fn}_g} & \ok \\ - & \qquad\seq{\var{\seq{y \mathjs{ = } v}}} \\ - & \qquad\mathit{exp} \\ - & \mathjs{\char125{}} \\ -\end{array} -\] -\end{minipage} -\end{lrbox} - -\[ -\begin{array}{c} -\multicolumn{1}{r}{\fbox{$\progjudge{\mathit{mod}}$}} -\rulebreak -\inferrule* [lab=\rel{T-Module}] - {\Delta = \{ \seq{x : \imm\,\imptype(\mathit{imp})}, \seq{g : \imm\,\funtype(\mathit{fn}_g)}, \seq{y : \mut\,\vartype(v)} \} \\\\ - %%\forall i . \impjudge{[g]}{[e]}{[b]}{\Delta}{\mathit{imp}_x} \\ - \seq{x}, \seq{y}, \seq{g}, [f], [\mathit{global}], [\mathit{foreign}], [\mathit{buffer}]\ \mbox{distinct} \\ - \forall i . \fnjudge{\Delta}{\mathit{fn}_f} \\ - \forall i . \expjudge{\Delta}{\mathit{exp}}} - {\usebox{\modjudge}} -% {\progjudge{\fun{[m]}{[g[, e[, b]]}{\mathjs{"use asm";}\ \seq{\mathit{imp}_x}\ \seq{\mathit{fn}_f}\ \seq{\var{\seq{y \mathjs{ = } v}}}\ \mathit{exp}}}} -\end{array} -\] - -For simplicity of the specification, we leave as an assumption that -the same $\mathit{global}$, $\mathit{foreign}$, and $\mathit{buffer}$ -variables are used consistently throughout the module. An actual -validator must check this assumption. Similarly, we assume the -existence of a single $\mathit{mask}$ constant used throughout the -module, which a real validator would have to check. - -%% \subsection{Import validation} - -%% Declarations in the import section of an $\mathjs{asm.js}$ module can -%% be known library functions, unknown FFI functions, typed array views, -%% or imported constants. - -%% \[ -%% \begin{array}{c} -%% \multicolumn{1}{r}{\fbox{$\impjudge{[g]}{[e]}{[b]}{\Delta}{\mathit{imp}}$}} -%% \rulebreak -%% \inferrule* [lab=\rel{T-ImportStd}] -%% {\iejudge{[g]}{[e]}{\mathit{ie}}{\Delta(x)}} -%% {\impjudge{[g]}{[e]}{[b]}{\Delta}{\var{x \mathjs{ = } \mathit{ie}}}} -%% \qquad -%% \inferrule* [lab=\rel{T-ImportFFI}] -%% {\iejudge{[g]}{[e]}{\mathit{ie}}{\epsilon} \\\\ -%% \Delta(x) = \Fun} -%% {\impjudge{[g]}{[e]}{[b]}{\Delta}{\var{x \mathjs{ = } \mathit{ie}}}} -%% \\ \\ -%% \inferrule* [lab=\rel{T-ImportInt}] -%% {\iejudge{[g]}{[e]}{\mathit{ie}}{\tau} \\\\ -%% \tau <: \intish \\ -%% \Delta(x) = \signed} -%% {\impjudge{[g]}{[e]}{[b]}{\Delta}{\var{x \mathjs{ = } \mathit{ie}\mathjs{|0}}}} -%% \qquad -%% \inferrule* [lab=\rel{T-ImportDouble}] -%% {\iejudge{[g]}{[e]}{\mathit{ie}}{\tau} \\\\ -%% \tau <: \doublish \\ -%% \Delta(x) = \double} -%% {\impjudge{[g]}{[e]}{[b]}{\Delta}{\var{x \mathjs{ = +}\mathit{ie}}}} -%% \\ \\ -%% \inferrule* [lab=\rel{T-ImportView}] -%% {\Delta(x) = V(y)} -%% {\impjudge{g}{[e]}{b}{\Delta}{\var{x \mathjs{ = new } g\mathjs{.}y(b)}}} -%% %% \\ \\ -%% %% \inferrule* [lab=\rel{T-ImportStd}] -%% %% {\Delta(x) = M(y)} -%% %% {\impjudge{[g]}{[e]}{[b]}{\Delta}{\var{x \mathjs{ = } e\mathjs{.}y}}} -%% %% \qquad -%% %% \inferrule* [lab=\rel{T-ImportFFI}] -%% %% {y \not\in\dom(M), \dom(A) \\\\ -%% %% \Delta(x) = \Fun} -%% %% {\impjudge{[g]}{e}{[b]}{\Delta}{\var{x \mathjs{ = } c\mathjs{.}y}}} -%% %% \\ \\ -%% %% \inferrule* [lab=\rel{T-View}] -%% %% {\Delta(x) = \view{n}{A(y)}} -%% %% {\impjudge{[g]}{e}{b}{\Delta}{\var{x \mathjs{ = new } c\mathjs{.}y(b)}}} -%% %% \\ \\ -%% %% \inferrule* [lab=\rel{T-ImportInt}] -%% %% {\Delta(x) = \int} -%% %% {\impjudge{[g]}{e}{[b]}{\Delta}{\var{x \mathjs{ = }c\mathjs{.}y\mathjs{|0}}}} -%% %% \qquad -%% %% \inferrule* [lab=\rel{T-ImportDouble}] -%% %% {\Delta(x) = \double} -%% %% {\impjudge{[g]}{e}{[b]}{\Delta}{\var{x \mathjs{ = +}c\mathjs{.}y}}} -%% \end{array} -%% \] - -%% \[ -%% \begin{array}{c} -%% \multicolumn{1}{r}{\fbox{$\iejudge{[g]}{[e]}{\mathit{ie}}{[\gamma]}$}} -%% \rulebreak -%% \inferrule* [lab=\rel{T-Global}] -%% {y \in \dom(G)} -%% {\iejudge{g}{[e]}{g\mathjs{.}y}{G(y)}} -%% \qquad -%% \inferrule* [lab=\rel{T-Math}] -%% {y \in \dom(M)} -%% {\iejudge{g}{[e]}{g\mathjs{.Math.}y}{M(y)}} -%% \qquad -%% \inferrule* [lab=\rel{T-FFI}] -%% { } -%% {\iejudge{[g]}{e}{e\mathjs{.}y}{\epsilon}} -%% \end{array} -%% \] - -\subsection{Function validation} - -Function validation proceeds in several steps. First, a local -environment is constructed with bindings for the parameters and local -variables, based on their annotations and initializers, -respectively. Next, the body of the function is checked in this -environment. Finally, if the function has a non-$\void$ return type, -the body is checked to ensure that all control flow paths definitely -return a value (see Section~\ref{sec:cfa}). - -\[ -\begin{array}{c} -\multicolumn{1}{r}{\fbox{$\fnjudge{\Delta}{\mathit{fn}}$}} -\rulebreak -\inferrule* [lab=\rel{T-Function}] - {\seq{x}, \seq{y}\ \mbox{distinct} \\ - \Delta(f) = \imm\,\funty{\seq{\sigma}}{\tau} \\ - \seq{\sigma} = \seq{\vartype(\mathit{ann}_x)} \\\\ - \sjudge{\Delta}{\{ \seq{x : \sigma}, \seq{y : \vartype(v)} \}}{\tau}{\mathit{ss}}} - {\fnjudge{\Delta}{\fun{f}{\seq{x}}{\seq{x\mathjs{ = }\mathit{ann}_x\mathjs{;}}\ \seq{\var{\seq{y\mathjs{ = }v}}}\ \mathit{ss}}}} -\end{array} -\] - -\subsection{Export validation} - -Export validation ensures that all exports are functions. - -\[ -\begin{array}{c} -\multicolumn{1}{r}{\fbox{$\expjudge{\Delta}{\mathit{exp}}$}} -\rulebreak -\inferrule* [lab=\rel{T-Singleton}] - {\Delta(f) = \imm\,\funty{\seq{\sigma}}{\tau}} - {\expjudge{\Delta}{\return{f}}} -\qquad -\inferrule* [lab=\rel{T-Module}] - {\forall f . \Delta(f) = \imm\,\funty{\seq{\sigma}}{\tau}} - {\expjudge{\Delta}{\return{\mathjs{\char123{} } \seq{x \mathjs{:} f} \mathjs{ \char125{}}}}} -\end{array} -\] - -\subsection{Statement list validation} - -\[ -\begin{array}{c} -\multicolumn{1}{r}{\fbox{$\sjudge{\Delta}{\Gamma}{\tau}{\mathit{ss}}$}} -\rulebreak -\inferrule* [lab=\rel{T-Statements}] - {\forall i . \sjudge{\Delta}{\Gamma}{\tau}{s_i}} - {\sjudge{\Delta}{\Gamma}{\tau}{\seq{s}}} -\end{array} -\] - - -\subsection{Statement validation} - -\newsavebox{\switchcontrol} -\begin{lrbox}{\switchcontrol} -\begin{minipage}[t]{2.87in} -\vspace{-.25in} -\[ -\varepsilon = \left\{ \begin{array}{ll} - \mustret & \mbox{if}\ \varepsilon_n = \mustret \land \forall i . \varepsilon_i \cup \emptyset = \emptyset \\ - \bigcup \varepsilon_i - \{ \epsilon \} & \mbox{otherwise} - \end{array} \right. -\] -\end{minipage} -\end{lrbox} - -\[ -\begin{array}{c} -\multicolumn{1}{r}{\fbox{$\sjudge{\Delta}{\Gamma}{\tau}{s}$}} -\rulebreak -\inferrule* [lab=\rel{T-Block}] - {\sjudge{\Delta}{\Gamma}{\tau}{\mathit{ss}}} - {\sjudge{\Delta}{\Gamma}{\tau}{\block{\mathit{ss}}}} -\qquad -\inferrule* [lab=\rel{T-ExprStmt}] - {\exprjudge{\Delta}{\Gamma}{e}{\sigma}} - {\sjudge{\Delta}{\Gamma}{\tau}{e\mathjs{;}}} -\qquad -\inferrule* [lab=\rel{T-EmptyStatement}] - { } - {\sjudge{\Delta}{\Gamma}{\tau}{\mathjs{;}}} -\\ \\ -\inferrule* [lab=\rel{T-If}] - {\exprjudge{\Delta}{\Gamma}{e}{\boolish} \\\\ - \sjudge{\Delta}{\Gamma}{\tau}{s}} - {\sjudge{\Delta}{\Gamma}{\tau}{\ifone{e}{s}}} -\qquad -\inferrule* [lab=\rel{T-IfElse}] - {\exprjudge{\Delta}{\Gamma}{e}{\boolish} \\\\ - \sjudge{\Delta}{\Gamma}{\tau}{s_1} \\ - \sjudge{\Delta}{\Gamma}{\tau}{s_2}} - {\sjudge{\Delta}{\Gamma}{\tau}{\iftwo{e}{s_1}{s_2}}} -\\ \\ -\inferrule* [lab=\rel{T-ReturnExpr}] - {\exprjudge{\Delta}{\Gamma}{\mathit{re}}{\tau} \\\\ - \rettype(\mathit{re}) = \tau} - {\sjudge{\Delta}{\Gamma}{\tau}{\return{\mathit{re}}}} -%% \qquad -%% \inferrule* [lab=\rel{T-ReturnDouble}] -%% {\exprjudge{\Delta}{\Gamma}{e}{\double}} -%% {\sjudge{\Delta}{\Gamma}{\double}{\return{\mathjs{+}e}}} -\qquad -\inferrule* [lab=\rel{T-ReturnVoid}] - { } - {\sjudge{\Delta}{\Gamma}{\void}{\mathtt{return;}}} -\\ \\ -\inferrule* [lab=\rel{T-While}] - {\exprjudge{\Delta}{\Gamma}{e}{\int} \\\\ - \sjudge{\Delta}{\Gamma}{\tau}{s}} - {\sjudge{\Delta}{\Gamma}{\tau}{\while{e}{s}}} -\qquad -\inferrule* [lab=\rel{T-DoWhile}] - {\sjudge{\Delta}{\Gamma}{\tau}{s} \\\\ - \exprjudge{\Delta}{\Gamma}{e}{\int}} - {\sjudge{\Delta}{\Gamma}{\tau}{\dowhile{s}{e}}} -\\ \\ -\inferrule* [lab=\rel{T-For}] - {[\exprjudge{\Delta}{\Gamma}{e_1}{\sigma_1}] \\ - [\exprjudge{\Delta}{\Gamma}{e_2}{\int}] \\ - [\exprjudge{\Delta}{\Gamma}{e_3}{\sigma_3}] \\\\ - \sjudge{\Delta}{\Gamma}{\tau}{s}} - {\sjudge{\Delta}{\Gamma}{\tau}{\for{[e_1]}{[e_2]}{[e_3]}{s}}} -\\ \\ -\inferrule* [lab=\rel{T-Break}] - { } - {\sjudge{\Delta}{\Gamma}{\tau}{\brkl{[\mathit{lab}]}}} -\qquad -\inferrule* [lab=\rel{T-Continue}] - { } - {\sjudge{\Delta}{\Gamma}{\tau}{\contl{[\mathit{lab}]}}} -\qquad -\inferrule* [lab=\rel{T-Label}] - {\sjudge{\Delta}{\Gamma}{\tau}{s}} - {\sjudge{\Delta}{\Gamma}{\tau}{\lab{\mathit{lab}}{s}}} -\\ \\ -\inferrule* [lab=\rel{T-Switch}] - {\exprjudge{\Delta}{\Gamma}{e}{\sigma} \\ - \sigma \in \{ \signed, \unsigned \} \\ - \forall i . \exprjudge{\Delta}{\Gamma}{v_i}{\sigma} \\\\ - \forall i . \sjudge{\Delta}{\Gamma}{\tau}{\mathit{ss}_i} \\ - [\sjudge{\Delta}{\Gamma}{\tau}{\mathit{ss}}]} - {\sjudge{\Delta}{\Gamma}{\tau}{\switch{e}{\seq{\mathjs{case }v_i\mathjs{:}\,\mathit{ss}_i}\ [\mathjs{default:}\,\mathit{ss}]}}} -\end{array} -\] - -\subsection{Case validation} - -\[ -\begin{array}{c} -\multicolumn{1}{r}{\fbox{$\sjudge{\Delta}{\Gamma}{\tau}{\mathit{cd}}$}} -\rulebreak -\inferrule* [lab=\rel{T-Case}] - {\sjudge{\Delta}{\Gamma}{\tau}{\mathit{ss}}} - {\sjudge{\Delta}{\Gamma}{\tau}{\mathjs{case }v\mathjs{:}\,\mathit{ss}}} -\qquad -\inferrule* [lab=\rel{T-Default}] - {\sjudge{\Delta}{\Gamma}{\tau}{\mathit{ss}}} - {\sjudge{\Delta}{\Gamma}{\tau}{\mathjs{default:}\,\mathit{ss}}} -\end{array} -\] - -%% \subsection{Must-return analysis} -%% \label{sec:cfa} - -%% \[ -%% \begin{array}{rcl} -%% \breaks(\seq{s}) & = & \bigcup_i \breaks(s_i) \\ -%% \breaks(\block{\mathit{ss}}) & = & \breaks(\mathit{ss}) \\ -%% \breaks(\ifone{e}{s}) & = & \breaks(s) \\ -%% \breaks(\iftwo{e}{s_1}{s_2}) & = & \breaks(s_1) \cup \breaks(s_2) \\ -%% \breaks(\while{e}{s}) & = & \breaks(s) - \{ \epsilon \} \\ -%% \breaks(\dowhile{s}{e}) & = & \breaks(s) - \{ \epsilon \} \\ -%% \breaks(\for{[e_1]}{[e_2]}{[e_3]}{s}) & = & \breaks(s) - \{ \epsilon \} \\ -%% \breaks(\brk) & = & \{ \epsilon \} \\ -%% \breaks(\brkl{\mathit{lab}}) & = & \{ \mathit{lab} \} \\ -%% \breaks(\lab{\mathit{lab}}{s}) & = & \breaks(s) - \{ \mathit{lab} \} \\ -%% \breaks(\switch{e}{\seq{\mathit{cd}}}) & = & \bigcup_i \breaks(\mathit{cd}_i) - \{ \epsilon \} \\ -%% \breaks(s) \mbox{ (otherwise)} & = & \emptyset \\ -%% \breaks(\mathjs{case }v\mathjs{:}\,\mathit{ss}) & = & \breaks(\mathit{ss}) \\ -%% \breaks(\mathjs{default:}\,\mathit{ss}) & = & \breaks(\mathit{ss}) \\ -%% \end{array} -%% \] - -%% \[ -%% \begin{array}{l} -%% \returns(\seq{s}) \\ -%% \qquad \mbox{if } \returns(s_m) \land \forall i < m . \breaks(s_m) = \emptyset \mbox{ for some } m \\ -%% \returns(\block{\mathit{ss}}) \\ -%% \qquad \mbox{if } \returns(ss) \\ -%% \returns(\iftwo{e}{s_1}{s_2}) \\ -%% \qquad \mbox{if } \returns(s_1) \land \returns(s_2) \\ -%% \returns(\dowhile{s}{e}) \\ -%% \qquad \mbox{if } \returns(s) \\ -%% \returns(\switch{e}{\seq{\mathit{cd}}}) \\ -%% \qquad \mbox{if } \returns(cd_n) \land \forall i . \breaks(cd_i) = \emptyset \\ -%% \returns(\mathjs{case }v\mathjs{:}\,\mathit{ss}) \\ -%% \qquad \mbox{if } \returns(\mathit{ss}) \\ -%% \returns(\mathjs{default:}\,\mathit{ss}) \\ -%% \qquad \mbox{if } \returns(\mathit{ss}) -%% \end{array} -%% \] - -\subsection{Expression validation} -\label{sec:exprjudge} - -\[ -(\Delta\cdot\Gamma)(x) = \left\{\begin{array}{ll} - \Gamma(x) & \mbox{if}\ x \in\dom(\Gamma) \\ - \gamma & \mbox{if}\ \Delta(x) = \mu\,\gamma \\ - \end{array} \right. -\] - -\[ -\begin{array}{lr} -\mbox{Expression validation} & \hfil \fbox{$\exprjudge{\Delta}{\Gamma}{e}{\tau}$} -\rulebreak -\multicolumn{2}{c}{ -\begin{array}{c} -\inferrule* [lab=\rel{T-Signed}] - {-2^{31} \leq i < 0} - {\exprjudge{\Delta}{\Gamma}{i}{\signed}} -\qquad -\inferrule* [lab=\rel{T-Fixnum}] - {0 \leq i < 2^{31}} - {\exprjudge{\Delta}{\Gamma}{i}{\fixnum}} -\qquad -\inferrule* [lab=\rel{T-Unsigned}] - {2^{31} \leq i < 2^{32}} - {\exprjudge{\Delta}{\Gamma}{i}{\unsigned}} -\\ \\ -\inferrule* [lab=\rel{T-Double}] - { } - {\exprjudge{\Delta}{\Gamma}{r}{\double}} -\qquad -\inferrule* [lab=\rel{T-VarRef}] - {(\Delta\cdot\Gamma)(x) = \tau} - {\exprjudge{\Delta}{\Gamma}{x}{\tau}} -\\ \\ -\inferrule* [lab=\rel{T-SetLocal}] - {\exprjudge{\Delta}{\Gamma}{e}{\tau} \\ - \tau <: \Gamma(x)} - {\exprjudge{\Delta}{\Gamma}{x\mathjs{ = }e}{\tau}} -\qquad -\inferrule* [lab=\rel{T-SetGlobal}] - {x \not\in\dom(\Gamma) \\ - \Delta(x) = \mut\,\sigma \\\\ - \exprjudge{\Delta}{\Gamma}{e}{\tau} \\ - \tau <: \sigma} - {\exprjudge{\Delta}{\Gamma}{x\mathjs{ = }e}{\tau}} -\\ \\ -\inferrule* [lab=\rel{T-LoadImm}] - {(\Delta\cdot\Gamma)(x) = \view{n}{\tau} \\\\ - i \equiv 0 \mod n \\ - 0 \leq i \leq \mathit{mask} \\\\ - \exprjudge{\Delta}{\Gamma}{e}{\intish}} - {\exprjudge{\Delta}{\Gamma}{\getprop{x}{i}}{\tau}} -\qquad -\inferrule* [lab=\rel{T-StoreImm}] - {(\Delta\cdot\Gamma)(x) = \view{n}{\tau} \\\\ - i \equiv 0 \mod n \\ - 0 \leq i \leq \mathit{mask} \\\\ - \exprjudge{\Delta}{\Gamma}{e_1}{\intish} \\ - \exprjudge{\Delta}{\Gamma}{e_2}{\tau}} - {\exprjudge{\Delta}{\Gamma}{\getprop{x}{i}\mathjs{ = }e_2}{\tau}} -\\ \\ -\inferrule* [lab=\rel{T-LoadByte}] - {(\Delta\cdot\Gamma)(x) = \view{1}{\intsm} \\\\ - \exprjudge{\Delta}{\Gamma}{e}{\intish}} - {\exprjudge{\Delta}{\Gamma}{\getprop{x}{e\mathjs{ \& } \mathit{mask}}}{\tau}} -\qquad -\inferrule* [lab=\rel{T-StoreByte}] - {(\Delta\cdot\Gamma)(x) = \view{1}{\intsm} \\\\ - \exprjudge{\Delta}{\Gamma}{e_1}{\intish} \\ - \exprjudge{\Delta}{\Gamma}{e_2}{\tau}} - {\exprjudge{\Delta}{\Gamma}{\getprop{x}{e_1\mathjs{ \& } \mathit{mask}}\mathjs{ = }e_2}{\tau}} -\\ \\ -\inferrule* [lab=\rel{T-Load}] - {(\Delta\cdot\Gamma)(x) = \view{n}{\tau} \\\\ - \mathit{shift} = \log_2(n) \\ - n > 1 \\\\ - \exprjudge{\Delta}{\Gamma}{e}{\intish}} - {\exprjudge{\Delta}{\Gamma}{\getprop{x}{\paren{e\mathjs{ \& } \mathit{mask}}\mathjs{ >> } \mathit{shift}}}{\tau}} -\qquad -\inferrule* [lab=\rel{T-Store}] - {(\Delta\cdot\Gamma)(x) = \view{n}{\tau} \\\\ - \mathit{shift} = \log_2(n) \\ - n > 1 \\\\ - \exprjudge{\Delta}{\Gamma}{e_1}{\intish} \\ - \exprjudge{\Delta}{\Gamma}{e_2}{\tau}} - {\exprjudge{\Delta}{\Gamma}{\getprop{x}{\paren{e_1\mathjs{ \& } \mathit{mask}}\mathjs{ >> } \mathit{shift}}\mathjs{ = }e_2}{\tau}} -\end{array} -} -\end{array} -\] - -\[ -\begin{array}{lr} -\mbox{Expression validation (cont'd)} & \hfil \fbox{$\exprjudge{\Delta}{\Gamma}{e}{\tau}$} -\rulebreak -\multicolumn{2}{c}{ -\begin{array}{c} -\inferrule* [lab=\rel{T-FunCall}] - {(\Delta\cdot\Gamma)(f) = \_ \land \funty{\seq{\sigma}}{\tau} \land \_ \\\\ - \forall i . \exprjudge{\Delta}{\Gamma}{e_i}{\sigma_i}} - {\exprjudge{\Delta}{\Gamma}{\funcall{f}{\seq{e}}}{\tau}} -\qquad -\inferrule* [lab=\rel{T-FFICall}] - {(\Delta\cdot\Gamma)(f) = \Fun \\\\ - %(\Delta\cdot\Gamma)(f) = \_ \land \funty{\ldots\sigma}{\tau} \land \_ \\\\ - \forall i . \exprjudge{\Delta}{\Gamma}{e_i}{\extern}} - {\exprjudge{\Delta}{\Gamma}{\funcall{f}{\seq{e}}}{\unk}} -\\ \\ -\inferrule* [lab=\rel{T-Unop}] - {\mathit{unop} : \_ \land \funty{\sigma}{\tau} \land \_ \\\\ - \exprjudge{\Delta}{\Gamma}{e}{\sigma}} - {\exprjudge{\Delta}{\Gamma}{\mathit{unop}\ e}{\tau}} -\qquad -\inferrule* [lab=\rel{T-Binop}] - {\mathit{binop} : \_ \land \funty{\sigma_1, \sigma_2}{\tau} \land \_ \\\\ - \exprjudge{\Delta}{\Gamma}{e_1}{\sigma_1} \\ - \exprjudge{\Delta}{\Gamma}{e_2}{\sigma_2}} - {\exprjudge{\Delta}{\Gamma}{e_1\ \mathit{binop}\ e_2}{\tau}} -\\ \\ -\inferrule* [lab=\rel{T-Multiary}] - {\forall i < n . \oplus_i \in \{ +, - \} \\ - n \leq 2^{20} \\\\ - \forall i \leq n . \exprjudge{\Delta}{\Gamma}{e_i}{\int}} - {\exprjudge{\Delta}{\Gamma}{e_1 \oplus_1 \ldots \oplus_{n-1} e_n}{\intish}} -\qquad -\inferrule* [lab=\rel{T-Cond}] - {\tau \in \{ \int, \double \} \\\\ - \exprjudge{\Delta}{\Gamma}{e_1}{\int} \\\\ - \exprjudge{\Delta}{\Gamma}{e_2}{\tau} \\ - \exprjudge{\Delta}{\Gamma}{e_3}{\tau}} - {\exprjudge{\Delta}{\Gamma}{\ternary{e_1}{e_2}{e_3}}{\tau}} -\\ \\ -\inferrule* [lab=\rel{T-Paren}] - {\forall i \leq n . \exprjudge{\Delta}{\Gamma}{e_i}{\tau_i}} - {\exprjudge{\Delta}{\Gamma}{\paren{\seq{e}}}{\tau_n}} -\qquad -\inferrule* [lab=\rel{T-Sub}] - {\exprjudge{\Delta}{\Gamma}{e}{\sigma} \\ - \sigma <: \tau} - {\exprjudge{\Delta}{\Gamma}{e}{\tau}} -\qquad -\inferrule* [lab=\rel{T-Cast}] - {\exprjudge{\Delta}{\Gamma}{e}{\double}} - {\exprjudge{\Delta}{\Gamma}{\mathjs{\~{}\~{}}e}{\signed}} -\end{array} -} -\end{array} -\] - -\end{document} diff --git a/historic/mathpartir.sty b/historic/mathpartir.sty deleted file mode 100644 index 6b526e2..0000000 --- a/historic/mathpartir.sty +++ /dev/null @@ -1,447 +0,0 @@ -% Mathpartir --- Math Paragraph for Typesetting Inference Rules -% -% Copyright (C) 2001, 2002, 2003, 2004, 2005 Didier R�my -% -% Author : Didier Remy -% Version : 1.2.0 -% Bug Reports : to author -% Web Site : http://pauillac.inria.fr/~remy/latex/ -% -% Mathpartir is free software; you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation; either version 2, or (at your option) -% any later version. -% -% Mathpartir is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details -% (http://pauillac.inria.fr/~remy/license/GPL). -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% File mathpartir.sty (LaTeX macros) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{mathpartir} - [2005/12/20 version 1.2.0 Math Paragraph for Typesetting Inference Rules] - -%% - -%% Identification -%% Preliminary declarations - -\RequirePackage {keyval} - -%% Options -%% More declarations - -%% PART I: Typesetting maths in paragraphe mode - -%% \newdimen \mpr@tmpdim -%% Dimens are a precious ressource. Uses seems to be local. -\let \mpr@tmpdim \@tempdima - -% To ensure hevea \hva compatibility, \hva should expands to nothing -% in mathpar or in inferrule -\let \mpr@hva \empty - -%% normal paragraph parametters, should rather be taken dynamically -\def \mpr@savepar {% - \edef \MathparNormalpar - {\noexpand \lineskiplimit \the\lineskiplimit - \noexpand \lineskip \the\lineskip}% - } - -\def \mpr@rulelineskip {\lineskiplimit=0.3em\lineskip=0.2em plus 0.1em} -\def \mpr@lesslineskip {\lineskiplimit=0.6em\lineskip=0.5em plus 0.2em} -\def \mpr@lineskip {\lineskiplimit=1.2em\lineskip=1.2em plus 0.2em} -\let \MathparLineskip \mpr@lineskip -\def \mpr@paroptions {\MathparLineskip} -\let \mpr@prebindings \relax - -\newskip \mpr@andskip \mpr@andskip 2em plus 0.5fil minus 0.5em - -\def \mpr@goodbreakand - {\hskip -\mpr@andskip \penalty -1000\hskip \mpr@andskip} -\def \mpr@and {\hskip \mpr@andskip} -\def \mpr@andcr {\penalty 50\mpr@and} -\def \mpr@cr {\penalty -10000\mpr@and} -\def \mpr@eqno #1{\mpr@andcr #1\hskip 0em plus -1fil \penalty 10} - -\def \mpr@bindings {% - \let \and \mpr@andcr - \let \par \mpr@andcr - \let \\\mpr@cr - \let \eqno \mpr@eqno - \let \hva \mpr@hva - } -\let \MathparBindings \mpr@bindings - -% \@ifundefined {ignorespacesafterend} -% {\def \ignorespacesafterend {\aftergroup \ignorespaces} - -\newenvironment{mathpar}[1][] - {$$\mpr@savepar \parskip 0em \hsize \linewidth \centering - \vbox \bgroup \mpr@prebindings \mpr@paroptions #1\ifmmode $\else - \noindent $\displaystyle\fi - \MathparBindings} - {\unskip \ifmmode $\fi\egroup $$\ignorespacesafterend} - -\newenvironment{mathparpagebreakable}[1][] - {\begingroup - \par - \mpr@savepar \parskip 0em \hsize \linewidth \centering - \mpr@prebindings \mpr@paroptions #1% - \vskip \abovedisplayskip \vskip -\lineskip% - \ifmmode \else $\displaystyle\fi - \MathparBindings - } - {\unskip - \ifmmode $\fi \par\endgroup - \vskip \belowdisplayskip - \noindent - \ignorespacesafterend} - -% \def \math@mathpar #1{\setbox0 \hbox {$\displaystyle #1$}\ifnum -% \wd0 < \hsize $$\box0$$\else \bmathpar #1\emathpar \fi} - -%%% HOV BOXES - -\def \mathvbox@ #1{\hbox \bgroup \mpr@normallineskip - \vbox \bgroup \tabskip 0em \let \\ \cr - \halign \bgroup \hfil $##$\hfil\cr #1\crcr \egroup \egroup - \egroup} - -\def \mathhvbox@ #1{\setbox0 \hbox {\let \\\qquad $#1$}\ifnum \wd0 < \hsize - \box0\else \mathvbox {#1}\fi} - - -%% Part II -- operations on lists - -\newtoks \mpr@lista -\newtoks \mpr@listb - -\long \def\mpr@cons #1\mpr@to#2{\mpr@lista {\\{#1}}\mpr@listb \expandafter -{#2}\edef #2{\the \mpr@lista \the \mpr@listb}} - -\long \def\mpr@snoc #1\mpr@to#2{\mpr@lista {\\{#1}}\mpr@listb \expandafter -{#2}\edef #2{\the \mpr@listb\the\mpr@lista}} - -\long \def \mpr@concat#1=#2\mpr@to#3{\mpr@lista \expandafter {#2}\mpr@listb -\expandafter {#3}\edef #1{\the \mpr@listb\the\mpr@lista}} - -\def \mpr@head #1\mpr@to #2{\expandafter \mpr@head@ #1\mpr@head@ #1#2} -\long \def \mpr@head@ #1#2\mpr@head@ #3#4{\def #4{#1}\def#3{#2}} - -\def \mpr@flatten #1\mpr@to #2{\expandafter \mpr@flatten@ #1\mpr@flatten@ #1#2} -\long \def \mpr@flatten@ \\#1\\#2\mpr@flatten@ #3#4{\def #4{#1}\def #3{\\#2}} - -\def \mpr@makelist #1\mpr@to #2{\def \mpr@all {#1}% - \mpr@lista {\\}\mpr@listb \expandafter {\mpr@all}\edef \mpr@all {\the - \mpr@lista \the \mpr@listb \the \mpr@lista}\let #2\empty - \def \mpr@stripof ##1##2\mpr@stripend{\def \mpr@stripped{##2}}\loop - \mpr@flatten \mpr@all \mpr@to \mpr@one - \expandafter \mpr@snoc \mpr@one \mpr@to #2\expandafter \mpr@stripof - \mpr@all \mpr@stripend - \ifx \mpr@stripped \empty \let \mpr@isempty 0\else \let \mpr@isempty 1\fi - \ifx 1\mpr@isempty - \repeat -} - -\def \mpr@rev #1\mpr@to #2{\let \mpr@tmp \empty - \def \\##1{\mpr@cons ##1\mpr@to \mpr@tmp}#1\let #2\mpr@tmp} - -%% Part III -- Type inference rules - -\newif \if@premisse -\newbox \mpr@hlist -\newbox \mpr@vlist -\newif \ifmpr@center \mpr@centertrue -\def \mpr@htovlist {% - \setbox \mpr@hlist - \hbox {\strut - \ifmpr@center \hskip -0.5\wd\mpr@hlist\fi - \unhbox \mpr@hlist}% - \setbox \mpr@vlist - \vbox {\if@premisse \box \mpr@hlist \unvbox \mpr@vlist - \else \unvbox \mpr@vlist \box \mpr@hlist - \fi}% -} -% OLD version -% \def \mpr@htovlist {% -% \setbox \mpr@hlist -% \hbox {\strut \hskip -0.5\wd\mpr@hlist \unhbox \mpr@hlist}% -% \setbox \mpr@vlist -% \vbox {\if@premisse \box \mpr@hlist \unvbox \mpr@vlist -% \else \unvbox \mpr@vlist \box \mpr@hlist -% \fi}% -% } - -\def \mpr@item #1{$\displaystyle #1$} -\def \mpr@sep{2em} -\def \mpr@blank { } -\def \mpr@hovbox #1#2{\hbox - \bgroup - \ifx #1T\@premissetrue - \else \ifx #1B\@premissefalse - \else - \PackageError{mathpartir} - {Premisse orientation should either be T or B} - {Fatal error in Package}% - \fi \fi - \def \@test {#2}\ifx \@test \mpr@blank\else - \setbox \mpr@hlist \hbox {}% - \setbox \mpr@vlist \vbox {}% - \if@premisse \let \snoc \mpr@cons \else \let \snoc \mpr@snoc \fi - \let \@hvlist \empty \let \@rev \empty - \mpr@tmpdim 0em - \expandafter \mpr@makelist #2\mpr@to \mpr@flat - \if@premisse \mpr@rev \mpr@flat \mpr@to \@rev \else \let \@rev \mpr@flat \fi - \def \\##1{% - \def \@test {##1}\ifx \@test \empty - \mpr@htovlist - \mpr@tmpdim 0em %%% last bug fix not extensively checked - \else - \setbox0 \hbox{\mpr@item {##1}}\relax - \advance \mpr@tmpdim by \wd0 - %\mpr@tmpdim 1.02\mpr@tmpdim - \ifnum \mpr@tmpdim < \hsize - \ifnum \wd\mpr@hlist > 0 - \if@premisse - \setbox \mpr@hlist - \hbox {\unhbox0 \hskip \mpr@sep \unhbox \mpr@hlist}% - \else - \setbox \mpr@hlist - \hbox {\unhbox \mpr@hlist \hskip \mpr@sep \unhbox0}% - \fi - \else - \setbox \mpr@hlist \hbox {\unhbox0}% - \fi - \else - \ifnum \wd \mpr@hlist > 0 - \mpr@htovlist - \mpr@tmpdim \wd0 - \fi - \setbox \mpr@hlist \hbox {\unhbox0}% - \fi - \advance \mpr@tmpdim by \mpr@sep - \fi - }% - \@rev - \mpr@htovlist - \ifmpr@center \hskip \wd\mpr@vlist\fi \box \mpr@vlist - \fi - \egroup -} - -%%% INFERENCE RULES - -\@ifundefined{@@over}{% - \let\@@over\over % fallback if amsmath is not loaded - \let\@@overwithdelims\overwithdelims - \let\@@atop\atop \let\@@atopwithdelims\atopwithdelims - \let\@@above\above \let\@@abovewithdelims\abovewithdelims - }{} - -%% The default - -\def \mpr@@fraction #1#2{\hbox {\advance \hsize by -0.5em - $\displaystyle {#1\mpr@over #2}$}} -\def \mpr@@nofraction #1#2{\hbox {\advance \hsize by -0.5em - $\displaystyle {#1\@@atop #2}$}} - -\let \mpr@fraction \mpr@@fraction - -%% A generic solution to arrow - -\def \mpr@make@fraction #1#2#3#4#5{\hbox {% - \def \mpr@tail{#1}% - \def \mpr@body{#2}% - \def \mpr@head{#3}% - \setbox1=\hbox{$#4$}\setbox2=\hbox{$#5$}% - \setbox3=\hbox{$\mkern -3mu\mpr@body\mkern -3mu$}% - \setbox3=\hbox{$\mkern -3mu \mpr@body\mkern -3mu$}% - \dimen0=\dp1\advance\dimen0 by \ht3\relax\dp1\dimen0\relax - \dimen0=\ht2\advance\dimen0 by \dp3\relax\ht2\dimen0\relax - \setbox0=\hbox {$\box1 \@@atop \box2$}% - \dimen0=\wd0\box0 - \box0 \hskip -\dimen0\relax - \hbox to \dimen0 {$% - \mathrel{\mpr@tail}\joinrel - \xleaders\hbox{\copy3}\hfil\joinrel\mathrel{\mpr@head}% - $}}} - -%% Old stuff should be removed in next version -\def \mpr@@nothing #1#2 - {$\lower 0.01pt \mpr@@nofraction {#1}{#2}$} -\def \mpr@@reduce #1#2{\hbox - {$\lower 0.01pt \mpr@@fraction {#1}{#2}\mkern -15mu\rightarrow$}} -\def \mpr@@rewrite #1#2#3{\hbox - {$\lower 0.01pt \mpr@@fraction {#2}{#3}\mkern -8mu#1$}} -\def \mpr@infercenter #1{\vcenter {\mpr@hovbox{T}{#1}}} - -\def \mpr@empty {} -\def \mpr@inferrule - {\bgroup - \ifnum \linewidth<\hsize \hsize \linewidth\fi - \mpr@rulelineskip - \let \and \qquad - \let \hva \mpr@hva - \let \@rulename \mpr@empty - \let \@rule@options \mpr@empty - \let \mpr@over \@@over - \mpr@inferrule@} -\newcommand {\mpr@inferrule@}[3][] - {\everymath={\displaystyle}% - \def \@test {#2}\ifx \empty \@test - \setbox0 \hbox {$\vcenter {\mpr@hovbox{B}{#3}}$}% - \else - \def \@test {#3}\ifx \empty \@test - \setbox0 \hbox {$\vcenter {\mpr@hovbox{T}{#2}}$}% - \else - \setbox0 \mpr@fraction {\mpr@hovbox{T}{#2}}{\mpr@hovbox{B}{#3}}% - \fi \fi - \def \@test {#1}\ifx \@test\empty \box0 - \else \vbox -%%% Suggestion de Francois pour les etiquettes longues -%%% {\hbox to \wd0 {\RefTirName {#1}\hfil}\box0}\fi - {\hbox {\RefTirName {#1}}\box0}\fi - \egroup} - -\def \mpr@vdotfil #1{\vbox to #1{\leaders \hbox{$\cdot$} \vfil}} - -% They are two forms -% \inferrule [label]{[premisses}{conclusions} -% or -% \inferrule* [options]{[premisses}{conclusions} -% -% Premisses and conclusions are lists of elements separated by \\ -% Each \\ produces a break, attempting horizontal breaks if possible, -% and vertical breaks if needed. -% -% An empty element obtained by \\\\ produces a vertical break in all cases. -% -% The former rule is aligned on the fraction bar. -% The optional label appears on top of the rule -% The second form to be used in a derivation tree is aligned on the last -% line of its conclusion -% -% The second form can be parameterized, using the key=val interface. The -% folloiwng keys are recognized: -% -% width set the width of the rule to val -% narrower set the width of the rule to val\hsize -% before execute val at the beginning/left -% lab put a label [Val] on top of the rule -% lskip add negative skip on the right -% left put a left label [Val] -% Left put a left label [Val], ignoring its width -% right put a right label [Val] -% Right put a right label [Val], ignoring its width -% leftskip skip negative space on the left-hand side -% rightskip skip negative space on the right-hand side -% vdots lift the rule by val and fill vertical space with dots -% after execute val at the end/right -% -% Note that most options must come in this order to avoid strange -% typesetting (in particular leftskip must preceed left and Left and -% rightskip must follow Right or right; vdots must come last -% or be only followed by rightskip. -% - -%% Keys that make sence in all kinds of rules -\def \mprset #1{\setkeys{mprset}{#1}} -\define@key {mprset}{andskip}[]{\mpr@andskip=#1} -\define@key {mprset}{lineskip}[]{\lineskip=#1} -\define@key {mprset}{lessskip}[]{\lineskip=0.5\lineskip} -\define@key {mprset}{flushleft}[]{\mpr@centerfalse} -\define@key {mprset}{center}[]{\mpr@centertrue} -\define@key {mprset}{rewrite}[]{\let \mpr@fraction \mpr@@rewrite} -\define@key {mprset}{atop}[]{\let \mpr@fraction \mpr@@nofraction} -\define@key {mprset}{myfraction}[]{\let \mpr@fraction #1} -\define@key {mprset}{fraction}[]{\def \mpr@fraction {\mpr@make@fraction #1}} -\define@key {mprset}{sep}{\def\mpr@sep{#1}} - -\newbox \mpr@right -\define@key {mpr}{flushleft}[]{\mpr@centerfalse} -\define@key {mpr}{center}[]{\mpr@centertrue} -\define@key {mpr}{rewrite}[]{\let \mpr@fraction \mpr@@rewrite} -\define@key {mpr}{myfraction}[]{\let \mpr@fraction #1} -\define@key {mpr}{fraction}[]{\def \mpr@fraction {\mpr@make@fraction #1}} -\define@key {mpr}{left}{\setbox0 \hbox {$\TirName {#1}\;$}\relax - \advance \hsize by -\wd0\box0} -\define@key {mpr}{width}{\hsize #1} -\define@key {mpr}{sep}{\def\mpr@sep{#1}} -\define@key {mpr}{before}{#1} -\define@key {mpr}{lab}{\let \RefTirName \TirName \def \mpr@rulename {#1}} -\define@key {mpr}{Lab}{\let \RefTirName \TirName \def \mpr@rulename {#1}} -\define@key {mpr}{narrower}{\hsize #1\hsize} -\define@key {mpr}{leftskip}{\hskip -#1} -\define@key {mpr}{reduce}[]{\let \mpr@fraction \mpr@@reduce} -\define@key {mpr}{rightskip} - {\setbox \mpr@right \hbox {\unhbox \mpr@right \hskip -#1}} -\define@key {mpr}{LEFT}{\setbox0 \hbox {$#1$}\relax - \advance \hsize by -\wd0\box0} -\define@key {mpr}{left}{\setbox0 \hbox {$\TirName {#1}\;$}\relax - \advance \hsize by -\wd0\box0} -\define@key {mpr}{Left}{\llap{$\TirName {#1}\;$}} -\define@key {mpr}{right} - {\setbox0 \hbox {$\;\TirName {#1}$}\relax \advance \hsize by -\wd0 - \setbox \mpr@right \hbox {\unhbox \mpr@right \unhbox0}} -\define@key {mpr}{RIGHT} - {\setbox0 \hbox {$#1$}\relax \advance \hsize by -\wd0 - \setbox \mpr@right \hbox {\unhbox \mpr@right \unhbox0}} -\define@key {mpr}{Right} - {\setbox \mpr@right \hbox {\unhbox \mpr@right \rlap {$\;\TirName {#1}$}}} -\define@key {mpr}{vdots}{\def \mpr@vdots {\@@atop \mpr@vdotfil{#1}}} -\define@key {mpr}{after}{\edef \mpr@after {\mpr@after #1}} - -\newcommand \mpr@inferstar@ [3][]{\setbox0 - \hbox {\let \mpr@rulename \mpr@empty \let \mpr@vdots \relax - \setbox \mpr@right \hbox{}% - $\setkeys{mpr}{#1}% - \ifx \mpr@rulename \mpr@empty \mpr@inferrule {#2}{#3}\else - \mpr@inferrule [{\mpr@rulename}]{#2}{#3}\fi - \box \mpr@right \mpr@vdots$} - \setbox1 \hbox {\strut} - \@tempdima \dp0 \advance \@tempdima by -\dp1 - \raise \@tempdima \box0} - -\def \mpr@infer {\@ifnextchar *{\mpr@inferstar}{\mpr@inferrule}} -\newcommand \mpr@err@skipargs[3][]{} -\def \mpr@inferstar*{\ifmmode - \let \@do \mpr@inferstar@ - \else - \let \@do \mpr@err@skipargs - \PackageError {mathpartir} - {\string\inferrule* can only be used in math mode}{}% - \fi \@do} - - -%%% Exports - -% Envirnonment mathpar - -\let \inferrule \mpr@infer - -% make a short name \infer is not already defined -\@ifundefined {infer}{\let \infer \mpr@infer}{} - -\def \TirNameStyle #1{\small \textsc{#1}} -\def \tir@name #1{\hbox {\small \TirNameStyle{#1}}} -\let \TirName \tir@name -\let \DefTirName \TirName -\let \RefTirName \TirName - -%%% Other Exports - -% \let \listcons \mpr@cons -% \let \listsnoc \mpr@snoc -% \let \listhead \mpr@head -% \let \listmake \mpr@makelist - - - - -\endinput diff --git a/historic/subtypes.graffle b/historic/subtypes.graffle deleted file mode 100644 index c6014d1..0000000 --- a/historic/subtypes.graffle +++ /dev/null @@ -1,956 +0,0 @@ - - - - - ActiveLayerIndex - 0 - ApplicationVersion - - com.omnigroup.OmniGraffle - 139.16.0.171715 - - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {576, 733}} - Class - SolidGraphic - ID - 2 - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - BaseZoom - 0 - CanvasOrigin - {0, 0} - ColumnAlign - 1 - ColumnSpacing - 36 - CreationDate - 2012-10-24 05:05:27 +0000 - Creator - David Herman - DisplayScale - 1 0/72 in = 1.0000 in - GraphDocumentVersion - 8 - GraphicsList - - - Class - LineGraphic - Head - - ID - 107 - - ID - 109 - Points - - {163.5, 443} - {103, 319} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 57 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 107 - Info - 1 - - ID - 113 - Points - - {195.5, 346} - {103, 319} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 7 - Info - 1 - - - - Bounds - {{68, 249}, {70, 70}} - Class - ShapedGraphic - ID - 107 - Magnets - - {0, 0.5} - - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 doublish} - - - - Bounds - {{438, 346}, {70, 70}} - Class - ShapedGraphic - ID - 104 - Magnets - - {0, -0.5} - - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 void} - - - - Class - LineGraphic - Head - - ID - 60 - Position - 0.95704245567321777 - - ID - 103 - Points - - {328.5, 443} - {294.29327151179314, 417.15985208749771} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 3 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 4 - Info - 2 - - ID - 93 - Points - - {381.5, 535} - {434.5, 513} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 91 - - - - Class - LineGraphic - Head - - ID - 3 - Info - 2 - - ID - 92 - Points - - {381.5, 535} - {328.5, 513} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 91 - Info - 1 - - - - Bounds - {{346.5, 535}, {70, 70}} - Class - ShapedGraphic - ID - 91 - Magnets - - {0, -0.5} - {0, 0.5} - - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 fixnum} - - - - Class - LineGraphic - Head - - ID - 71 - - ID - 112 - Points - - {195.5, 346} - {288, 319} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 7 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 71 - Info - 1 - - ID - 72 - Points - - {380.5, 346} - {288, 319} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 5 - - - - Bounds - {{253, 249}, {70, 70}} - Class - ShapedGraphic - ID - 71 - Magnets - - {0, 0.5} - - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 intish} - - - - Class - LineGraphic - Head - - ID - 11 - - ID - 60 - Points - - {434.5, 443} - {288, 416} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 4 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 11 - - ID - 58 - Points - - {163.5, 443} - {288, 416} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 57 - Info - 1 - - - - Bounds - {{128.5, 443}, {70, 70}} - Class - ShapedGraphic - ID - 57 - Magnets - - {0, -0.5} - - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 double} - - - - Class - LineGraphic - Head - - ID - 5 - - ID - 20 - Points - - {434.5, 443} - {380.5, 416} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 4 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 5 - Info - 2 - - ID - 18 - Points - - {328.5, 443} - {380.5, 416} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 3 - Info - 1 - - - - Bounds - {{253, 346}, {70, 70}} - Class - ShapedGraphic - ID - 11 - Magnets - - {0, 0.5} - {0, -0.5} - - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 extern} - - - - Bounds - {{160.5, 346}, {70, 70}} - Class - ShapedGraphic - ID - 7 - Magnets - - {0, -0.5} - {0, 0.49999999999999956} - - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 unknown} - - - - Bounds - {{345.5, 346}, {70, 70}} - Class - ShapedGraphic - ID - 5 - Magnets - - {0, -0.5} - {0, 0.5} - - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 int} - - - - Bounds - {{399.5, 443}, {70, 70}} - Class - ShapedGraphic - ID - 4 - Magnets - - {0, -0.5} - {0, 0.5} - - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 unsigned} - - - - Bounds - {{293.5, 443}, {70, 70}} - Class - ShapedGraphic - ID - 3 - Magnets - - {0, -0.5} - {0, 0.5} - - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 signed} - - - - GridInfo - - GuidesLocked - NO - GuidesVisible - YES - HPages - 1 - ImageCounter - 1 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - LinksVisible - NO - MagnetsVisible - NO - MasterSheets - - ModificationDate - 2013-01-15 05:36:58 +0000 - Modifier - David Herman - NotesVisible - NO - Orientation - 2 - OriginVisible - NO - PageBreaks - YES - PrintInfo - - NSBottomMargin - - float - 41 - - NSHorizonalPagination - - coded - BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG - - NSLeftMargin - - float - 18 - - NSPaperSize - - size - {612, 792} - - NSPrintReverseOrientation - - int - 0 - - NSPrinter - - coded - BAtzdHJlYW10eXBlZIHoA4QBQISEhAlOU1ByaW50ZXIAhIQITlNPYmplY3QAhZKEhIQITlNTdHJpbmcBlIQBKw1NVFYyLUh5cGVyaW9uhoY= - - NSPrinterName - - string - MTV2-Hyperion - - NSRightMargin - - float - 18 - - NSTopMargin - - float - 18 - - - PrintOnePage - - ReadOnly - NO - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - SmartAlignmentGuidesActive - YES - SmartDistanceGuidesActive - YES - UniqueID - 1 - UseEntirePage - - VPages - 1 - WindowInfo - - CurrentSheet - 0 - ExpandedCanvases - - - name - Canvas 1 - - - Frame - {{40, 73}, {1005, 673}} - ListView - - OutlineWidth - 142 - RightSidebar - - ShowRuler - - Sidebar - - SidebarWidth - 120 - VisibleRegion - {{-147, 138}, {870, 534}} - Zoom - 1 - ZoomValues - - - Canvas 1 - 1 - 0.5 - - - - - diff --git a/historic/subtypes.png b/historic/subtypes.png deleted file mode 100644 index fdc4783..0000000 Binary files a/historic/subtypes.png and /dev/null differ diff --git a/html/Makefile b/html/Makefile deleted file mode 100644 index b76b7f7..0000000 --- a/html/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -index.html: index.src.html - anolis index.src.html index.html diff --git a/html/aot.graffle b/html/aot.graffle deleted file mode 100644 index 7fe7005..0000000 --- a/html/aot.graffle +++ /dev/null @@ -1,2886 +0,0 @@ - - - - - ApplicationVersion - - com.omnigroup.OmniGraffle - 139.16.0.171715 - - CreationDate - 2013-02-05 00:30:07 +0000 - Creator - David Herman - GraphDocumentVersion - 8 - GuidesLocked - NO - GuidesVisible - YES - ImageCounter - 1 - LinksVisible - NO - MagnetsVisible - NO - MasterSheets - - ModificationDate - 2013-02-05 02:01:46 +0000 - Modifier - David Herman - NotesVisible - NO - OriginVisible - NO - PageBreaks - YES - PrintInfo - - NSBottomMargin - - float - 41 - - NSHorizonalPagination - - coded - BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG - - NSLeftMargin - - float - 18 - - NSPaperSize - - size - {612, 792} - - NSPrintReverseOrientation - - int - 0 - - NSPrinter - - coded - BAtzdHJlYW10eXBlZIHoA4QBQISEhAlOU1ByaW50ZXIAhIQITlNPYmplY3QAhZKEhIQITlNTdHJpbmcBlIQBKw1NVFYyLUh5cGVyaW9uhoY= - - NSPrinterName - - string - MTV2-Hyperion - - NSRightMargin - - float - 18 - - NSTopMargin - - float - 18 - - - ReadOnly - NO - Sheets - - - ActiveLayerIndex - 0 - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {576, 733}} - Class - SolidGraphic - FontInfo - - Font - Helvetica - Size - 11 - - ID - 2 - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - BaseZoom - 0 - CanvasOrigin - {0, 0} - ColumnAlign - 1 - ColumnSpacing - 36 - DisplayScale - 1 0/72 in = 1 0/72 in - GraphicsList - - - Bounds - {{237.44252562522888, 107.83473449611662}, {52, 24}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 12 - - ID - 52 - Line - - ID - 27 - Position - 0.44252562522888184 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 compile} - - Wrap - NO - - - Bounds - {{377.56691652782985, 569.02245956890829}, {29, 24}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 12 - - ID - 51 - Line - - ID - 42 - Position - 0.43549069762229919 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 call} - - Wrap - NO - - - Bounds - {{134.5, 444.00000013452996}, {29, 24}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 12 - - ID - 50 - Line - - ID - 41 - Position - 0.44654077291488647 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 call} - - Wrap - NO - - - Bounds - {{386.61223285313872, 429.82491346534033}, {36, 24}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 12 - - ID - 49 - Line - - ID - 38 - Position - 0.47824451327323914 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 pass} - - Wrap - NO - - - Bounds - {{252.21298050501559, 388.07991023910773}, {26, 24}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 12 - - ID - 48 - Line - - ID - 34 - Position - 0.53825199604034424 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 fail} - - Wrap - NO - - - Bounds - {{377.56749568208238, 321.04651663910857}, {29, 24}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 12 - - ID - 47 - Line - - ID - 33 - Position - 0.43590256571769714 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 link} - - Wrap - NO - - - Bounds - {{308.2677336460626, 206.24097881942564}, {36, 24}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 12 - - ID - 45 - Line - - ID - 26 - Position - 0.49703007936477661 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 pass} - - Wrap - NO - - - Bounds - {{192.00115339767984, 210.00151812586623}, {26, 24}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 12 - - ID - 44 - Line - - ID - 25 - Position - 0.49317824840545654 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 fail} - - Wrap - NO - - - Bounds - {{134.06417065858841, 323.99194068215047}, {29, 24}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 12 - - ID - 43 - Line - - ID - 32 - Position - 0.56417065858840942 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 link} - - Wrap - NO - - - Class - LineGraphic - Head - - ID - 40 - Info - 2 - - ID - 42 - Points - - {391.45454465425928, 555.58181865046595} - {392.86070987641898, 614.00015239982883} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 36 - - - - Class - LineGraphic - Head - - ID - 39 - - ID - 41 - Points - - {149, 420.50001569726555} - {149, 500} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 30 - Info - 1 - - - - Bounds - {{347.87274169921875, 614.50000762939453}, {90, 36}} - Class - ShapedGraphic - ID - 40 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 execute} - VerticalPad - 0 - - - - Bounds - {{104, 500}, {90, 36}} - Class - ShapedGraphic - ID - 39 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 interpret} - VerticalPad - 0 - - - - Class - LineGraphic - Head - - ID - 37 - - ID - 38 - Points - - {415.37274169921875, 407.75} - {392.87272644042969, 478.99998305181191} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 31 - Info - 6 - - - - Class - Group - Graphics - - - Class - LineGraphic - ID - 36 - Points - - {391.45454465425928, 555.58181865046595} - {429.74545288085938, 555.58181865046595} - - Style - - stroke - - HeadArrow - 0 - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{356, 479.00000219726593}, {73.745452880859375, 76.581816453200091}} - Class - ShapedGraphic - ID - 37 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {0.35562666177031677, -0.35146732521269541} - - Shape - Circle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 executable} - VerticalPad - 0 - - - - ID - 35 - - - Class - LineGraphic - Head - - ID - 30 - Info - 3 - - ID - 34 - Points - - {370.37274169921875, 407.75} - {175.00001299999994, 393.50000219726564} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 31 - Info - 5 - - - - Class - LineGraphic - Head - - ID - 31 - - ID - 33 - Points - - {391.45454465425951, 307.58181818181822} - {392.86070987564023, 366.00014479883106} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 20 - - - - Class - LineGraphic - Head - - ID - 30 - Info - 2 - - ID - 32 - Points - - {148, 296.50000219726564} - {149, 366.49998869726574} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 23 - - - - Bounds - {{347.87274169921875, 366.5}, {90, 55.000000000000014}} - Class - ShapedGraphic - ID - 31 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {-0.25, 0.25} - {0.25, 0.25} - - Shape - Diamond - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 runtime checks} - VerticalPad - 0 - - - - Class - Group - Graphics - - - Class - LineGraphic - ID - 29 - Points - - {148, 420.50000219726564} - {175, 420.50000219726564} - - Style - - stroke - - HeadArrow - 0 - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{123, 366.50000219726564}, {52, 54}} - Class - ShapedGraphic - ID - 30 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {0.35562666177031677, -0.35146732521269541} - - Shape - Circle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 AST} - VerticalPad - 0 - - - - ID - 28 - - - Class - LineGraphic - Head - - ID - 3 - - ID - 27 - Points - - {263, 93.507999999999981} - {264, 153} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 17 - - - - Class - LineGraphic - Head - - ID - 21 - Info - 5 - - ID - 26 - Points - - {286.5, 194.25} - {366.51071825851517, 242.51866585235047} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 3 - Info - 6 - - - - Class - LineGraphic - Head - - ID - 24 - Info - 5 - - ID - 25 - Points - - {241.5, 194.25} - {167.49258641205648, 250.52076663578009} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 3 - Info - 5 - - - - Class - Group - Graphics - - - Class - LineGraphic - ID - 23 - Points - - {148, 296.50000219726564} - {175, 296.50000219726564} - - Style - - stroke - - HeadArrow - 0 - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{123, 242.50000219726564}, {52, 54}} - Class - ShapedGraphic - ID - 24 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {0.35562666177031677, -0.35146732521269541} - - Shape - Circle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 AST} - VerticalPad - 0 - - - - ID - 22 - - - Class - Group - Graphics - - - Class - LineGraphic - ID - 20 - Points - - {391.45454465425951, 307.58181818181822} - {429.74545288085943, 307.58181818181822} - - Style - - stroke - - HeadArrow - 0 - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{356.00000000000006, 231.00000000000017}, {73.745452880859304, 76.581818181818193}} - Class - ShapedGraphic - ID - 21 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {-0.35747299870141269, -0.34959007077890236} - - Shape - Circle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 AST + executable} - VerticalPad - 0 - - - - ID - 19 - - - Class - Group - Graphics - - - Class - LineGraphic - ID - 17 - Points - - {263, 93.507999999999981} - {290, 93.507999999999981} - - Style - - stroke - - HeadArrow - 0 - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{238, 39.507999999999967}, {52, 54}} - Class - ShapedGraphic - ID - 18 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Circle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 AST} - VerticalPad - 0 - - - - ID - 16 - - - Bounds - {{219, 153}, {90, 55.000000000000014}} - Class - ShapedGraphic - ID - 3 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {-0.25, 0.25} - {0.25, 0.25} - - Shape - Diamond - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 type\ -check} - VerticalPad - 0 - - - - GridInfo - - HPages - 1 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - Orientation - 2 - PrintOnePage - - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - UniqueID - 1 - VPages - 1 - - - ActiveLayerIndex - 0 - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {1152, 733}} - Class - SolidGraphic - ID - 2 - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - BaseZoom - 0 - CanvasOrigin - {0, 0} - ColumnAlign - 1 - ColumnSpacing - 36 - DisplayScale - 1 0/72 in = 1.0000 in - GraphicsList - - - Bounds - {{648.6817626953125, 146.29090881347651}, {19, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 72 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 call} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{504.24546813964844, 322}, {19, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 71 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 call} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{463.74545288085938, 228.5}, {16, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 70 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 fail} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{510.24542236328125, 146.29090881347656}, {26, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 69 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 pass} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{374.74545288085938, 322.00001525878906}, {19, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 68 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 link} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{374.74545288085938, 146.29090881347656}, {19, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 67 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 link} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{231, 286}, {16, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 66 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 fail} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{221, 177.79090881347656}, {26, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 65 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 pass} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{97.436370849609375, 219}, {42, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 64 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 compile} - VerticalPad - 0 - - Wrap - NO - - - Class - LineGraphic - Head - - ID - 30 - Info - 4 - - ID - 61 - Points - - {348.87275469921866, 308.00000439453129} - {427.74543988085946, 308.00000219726564} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 24 - Info - 3 - - - - Class - LineGraphic - Head - - ID - 39 - - ID - 60 - Points - - {479.74546588085929, 308.00000219726564} - {547.7454833984375, 308.5} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 30 - - - - Class - LineGraphic - Head - - ID - 40 - Info - 4 - - ID - 59 - Points - - {629.61818249886312, 173.29091042386594} - {686.74539184570312, 173.79090881347656} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 37 - - - - Class - LineGraphic - Head - - ID - 30 - - ID - 58 - Points - - {453.74545288085938, 201.29090881347656} - {453.74545288085938, 280.99998869726574} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 31 - - - - Class - LineGraphic - Head - - ID - 37 - Info - 4 - - ID - 57 - Points - - {498.74545288085938, 173.79090881347656} - {555.8726927452775, 173.29091042386594} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 31 - Info - 3 - - - - Class - LineGraphic - Head - - ID - 31 - - ID - 56 - Points - - {359.74547131722244, 173.29090909090911} - {408.74545288085938, 173.79090881347656} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 21 - Info - 3 - - - - Class - LineGraphic - Head - - ID - 24 - - ID - 55 - Points - - {214.5, 249.25} - {296.87272869921884, 308.00000439453129} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 3 - Info - 6 - - - - Class - LineGraphic - Head - - ID - 21 - - ID - 54 - Points - - {214.49999999999994, 221.74999999999994} - {285.99998156363694, 173.29090909090911} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 3 - Info - 7 - - - - Class - LineGraphic - Head - - ID - 3 - Info - 4 - - ID - 53 - Points - - {89.872754699218689, 235} - {147, 235.5} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 18 - Info - 3 - - - - Bounds - {{686.74539184570312, 155.79090881347656}, {90, 36}} - Class - ShapedGraphic - ID - 40 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 execute} - VerticalPad - 0 - - - - Class - Group - Graphics - - - Class - LineGraphic - ID - 36 - Points - - {591.3272558358999, 211.58181865046589} - {629.6181640625, 211.58181865046589} - - Style - - stroke - - HeadArrow - 0 - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{555.87271118164062, 135.0000021972659}, {73.745452880859375, 76.581816453200091}} - Class - ShapedGraphic - ID - 37 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {0.35562666177031677, -0.35146732521269541} - - Shape - Circle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 executable} - VerticalPad - 0 - - - - ID - 35 - - - Bounds - {{408.74545288085938, 146.29090881347656}, {90, 55.000000000000014}} - Class - ShapedGraphic - ID - 31 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {-0.25, 0.25} - {0.25, 0.25} - {0.24999999999999911, -0.25000000000000044} - - Shape - Diamond - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 runtime checks} - VerticalPad - 0 - - - - Class - Group - Graphics - - - Class - LineGraphic - ID - 20 - Points - - {321.45454465425951, 211.58181818181811} - {359.74545288085943, 211.58181818181811} - - Style - - stroke - - HeadArrow - 0 - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{286.00000000000006, 135}, {73.745452880859304, 76.581818181818193}} - Class - ShapedGraphic - ID - 21 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {-0.35747299870141269, -0.34959007077890236} - - Shape - Circle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 AST + executable} - VerticalPad - 0 - - - - ID - 19 - - - Bounds - {{547.7454833984375, 290.5}, {90, 36}} - Class - ShapedGraphic - ID - 39 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 interpret} - VerticalPad - 0 - - - - Class - Group - Graphics - - - Class - LineGraphic - ID - 29 - Points - - {452.74545288085938, 335.00000219726564} - {479.74545288085938, 335.00000219726564} - - Style - - stroke - - HeadArrow - 0 - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{427.74545288085938, 281.00000219726564}, {52, 54}} - Class - ShapedGraphic - ID - 30 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {0.35562666177031677, -0.35146732521269541} - - Shape - Circle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 AST} - VerticalPad - 0 - - - - ID - 28 - - - Class - Group - Graphics - - - Class - LineGraphic - ID - 23 - Points - - {321.87274169921875, 335.00000439453129} - {348.87274169921875, 335.00000439453129} - - Style - - stroke - - HeadArrow - 0 - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{296.87274169921875, 281.00000439453129}, {52, 54}} - Class - ShapedGraphic - ID - 24 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {0.35562666177031677, -0.35146732521269541} - - Shape - Circle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 AST} - VerticalPad - 0 - - - - ID - 22 - - - Bounds - {{147, 208}, {90, 55.000000000000014}} - Class - ShapedGraphic - ID - 3 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - {-0.25, 0.25} - {0.25, 0.25} - {0.24999999999999956, -0.25000000000000089} - - Shape - Diamond - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 type\ -check} - VerticalPad - 0 - - - - Class - Group - Graphics - - - Class - LineGraphic - ID - 17 - Points - - {62.87274169921875, 262} - {89.87274169921875, 262} - - Style - - stroke - - HeadArrow - 0 - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{37.87274169921875, 208}, {52, 54}} - Class - ShapedGraphic - ID - 18 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Circle - Style - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 AST} - VerticalPad - 0 - - - - ID - 16 - - - GridInfo - - HPages - 2 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - Orientation - 2 - PrintOnePage - - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 2 - UniqueID - 2 - VPages - 1 - - - SmartAlignmentGuidesActive - YES - SmartDistanceGuidesActive - YES - UseEntirePage - - WindowInfo - - CurrentSheet - 1 - ExpandedCanvases - - - name - Canvas 1 - - - Frame - {{57, 11}, {1106, 735}} - ListView - - OutlineWidth - 142 - RightSidebar - - ShowRuler - - Sidebar - - SidebarWidth - 120 - VisibleRegion - {{0, 0}, {971, 596}} - Zoom - 1 - ZoomValues - - - Canvas 1 - 1 - 2 - - - Canvas 2 - 1 - 1 - - - - - diff --git a/html/aot.png b/html/aot.png deleted file mode 100644 index 20ce539..0000000 Binary files a/html/aot.png and /dev/null differ diff --git a/html/github.css b/html/github.css deleted file mode 100644 index 47fc265..0000000 --- a/html/github.css +++ /dev/null @@ -1,127 +0,0 @@ -/* - -github.com style (c) Vasily Polovnyov - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #333; - background: #f8f8f8; -} - -.hljs-comment, -.hljs-template_comment, -.diff .hljs-header, -.hljs-javadoc { - color: #998; - font-style: italic; -} - -.hljs-keyword, -.css .rule .hljs-keyword, -.hljs-winutils, -.javascript .hljs-title, -.nginx .hljs-title, -.hljs-subst, -.hljs-request, -.hljs-status { - color: #333; - font-weight: bold; -} - -.hljs-number, -.hljs-hexcolor, -.ruby .hljs-constant { - color: #099; -} - -.hljs-string, -.hljs-tag .hljs-value, -.hljs-phpdoc, -.tex .hljs-formula { - color: #d14; -} - -.hljs-title, -.hljs-id, -.coffeescript .hljs-params, -.scss .hljs-preprocessor { - color: #900; - font-weight: bold; -} - -.javascript .hljs-title, -.lisp .hljs-title, -.clojure .hljs-title, -.hljs-subst { - font-weight: normal; -} - -.hljs-class .hljs-title, -.haskell .hljs-type, -.vhdl .hljs-literal, -.tex .hljs-command { - color: #458; - font-weight: bold; -} - -.hljs-tag, -.hljs-tag .hljs-title, -.hljs-rules .hljs-property, -.django .hljs-tag .hljs-keyword { - color: #000080; - font-weight: normal; -} - -.hljs-attribute, -.hljs-variable, -.lisp .hljs-body { - color: #008080; -} - -.hljs-regexp { - color: #009926; -} - -.hljs-symbol, -.ruby .hljs-symbol .hljs-string, -.lisp .hljs-keyword, -.tex .hljs-special, -.hljs-prompt { - color: #990073; -} - -.hljs-built_in, -.lisp .hljs-title, -.clojure .hljs-built_in { - color: #0086b3; -} - -.hljs-preprocessor, -.hljs-pragma, -.hljs-pi, -.hljs-doctype, -.hljs-shebang, -.hljs-cdata { - color: #999; - font-weight: bold; -} - -.hljs-deletion { - background: #fdd; -} - -.hljs-addition { - background: #dfd; -} - -.diff .hljs-change { - background: #0086b3; -} - -.hljs-chunk { - color: #aaa; -} diff --git a/html/highlight.pack.js b/html/highlight.pack.js deleted file mode 100644 index 15b173a..0000000 --- a/html/highlight.pack.js +++ /dev/null @@ -1 +0,0 @@ -var hljs=new function(){function j(v){return v.replace(/&/gm,"&").replace(//gm,">")}function t(v){return v.nodeName.toLowerCase()}function h(w,x){var v=w&&w.exec(x);return v&&v.index==0}function r(w){var v=(w.className+" "+(w.parentNode?w.parentNode.className:"")).split(/\s+/);v=v.map(function(x){return x.replace(/^lang(uage)?-/,"")});return v.filter(function(x){return i(x)||x=="no-highlight"})[0]}function o(x,y){var v={};for(var w in x){v[w]=x[w]}if(y){for(var w in y){v[w]=y[w]}}return v}function u(x){var v=[];(function w(y,z){for(var A=y.firstChild;A;A=A.nextSibling){if(A.nodeType==3){z+=A.nodeValue.length}else{if(t(A)=="br"){z+=1}else{if(A.nodeType==1){v.push({event:"start",offset:z,node:A});z=w(A,z);v.push({event:"stop",offset:z,node:A})}}}}return z})(x,0);return v}function q(w,y,C){var x=0;var F="";var z=[];function B(){if(!w.length||!y.length){return w.length?w:y}if(w[0].offset!=y[0].offset){return(w[0].offset"}function E(G){F+=""}function v(G){(G.event=="start"?A:E)(G.node)}while(w.length||y.length){var D=B();F+=j(C.substr(x,D[0].offset-x));x=D[0].offset;if(D==w){z.reverse().forEach(E);do{v(D.splice(0,1)[0]);D=B()}while(D==w&&D.length&&D[0].offset==x);z.reverse().forEach(A)}else{if(D[0].event=="start"){z.push(D[0].node)}else{z.pop()}v(D.splice(0,1)[0])}}return F+j(C.substr(x))}function m(y){function v(z){return(z&&z.source)||z}function w(A,z){return RegExp(v(A),"m"+(y.cI?"i":"")+(z?"g":""))}function x(D,C){if(D.compiled){return}D.compiled=true;D.k=D.k||D.bK;if(D.k){var z={};var E=function(G,F){if(y.cI){F=F.toLowerCase()}F.split(" ").forEach(function(H){var I=H.split("|");z[I[0]]=[G,I[1]?Number(I[1]):1]})};if(typeof D.k=="string"){E("keyword",D.k)}else{Object.keys(D.k).forEach(function(F){E(F,D.k[F])})}D.k=z}D.lR=w(D.l||/\b[A-Za-z0-9_]+\b/,true);if(C){if(D.bK){D.b="\\b("+D.bK.split(" ").join("|")+")\\b"}if(!D.b){D.b=/\B|\b/}D.bR=w(D.b);if(!D.e&&!D.eW){D.e=/\B|\b/}if(D.e){D.eR=w(D.e)}D.tE=v(D.e)||"";if(D.eW&&C.tE){D.tE+=(D.e?"|":"")+C.tE}}if(D.i){D.iR=w(D.i)}if(D.r===undefined){D.r=1}if(!D.c){D.c=[]}var B=[];D.c.forEach(function(F){if(F.v){F.v.forEach(function(G){B.push(o(F,G))})}else{B.push(F=="self"?D:F)}});D.c=B;D.c.forEach(function(F){x(F,D)});if(D.starts){x(D.starts,C)}var A=D.c.map(function(F){return F.bK?"\\.?("+F.b+")\\.?":F.b}).concat([D.tE,D.i]).map(v).filter(Boolean);D.t=A.length?w(A.join("|"),true):{exec:function(F){return null}};D.continuation={}}x(y)}function c(S,L,J,R){function v(U,V){for(var T=0;T";U+=Z+'">';return U+X+Y}function N(){if(!I.k){return j(C)}var T="";var W=0;I.lR.lastIndex=0;var U=I.lR.exec(C);while(U){T+=j(C.substr(W,U.index-W));var V=E(I,U);if(V){H+=V[1];T+=w(V[0],j(U[0]))}else{T+=j(U[0])}W=I.lR.lastIndex;U=I.lR.exec(C)}return T+j(C.substr(W))}function F(){if(I.sL&&!f[I.sL]){return j(C)}var T=I.sL?c(I.sL,C,true,I.continuation.top):e(C);if(I.r>0){H+=T.r}if(I.subLanguageMode=="continuous"){I.continuation.top=T.top}return w(T.language,T.value,false,true)}function Q(){return I.sL!==undefined?F():N()}function P(V,U){var T=V.cN?w(V.cN,"",true):"";if(V.rB){D+=T;C=""}else{if(V.eB){D+=j(U)+T;C=""}else{D+=T;C=U}}I=Object.create(V,{parent:{value:I}})}function G(T,X){C+=T;if(X===undefined){D+=Q();return 0}var V=v(X,I);if(V){D+=Q();P(V,X);return V.rB?0:X.length}var W=z(I,X);if(W){var U=I;if(!(U.rE||U.eE)){C+=X}D+=Q();do{if(I.cN){D+=""}H+=I.r;I=I.parent}while(I!=W.parent);if(U.eE){D+=j(X)}C="";if(W.starts){P(W.starts,"")}return U.rE?0:X.length}if(A(X,I)){throw new Error('Illegal lexeme "'+X+'" for mode "'+(I.cN||"")+'"')}C+=X;return X.length||1}var M=i(S);if(!M){throw new Error('Unknown language: "'+S+'"')}m(M);var I=R||M;var D="";for(var K=I;K!=M;K=K.parent){if(K.cN){D+=w(K.cN,D,true)}}var C="";var H=0;try{var B,y,x=0;while(true){I.t.lastIndex=x;B=I.t.exec(L);if(!B){break}y=G(L.substr(x,B.index-x),B[0]);x=B.index+y}G(L.substr(x));for(var K=I;K.parent;K=K.parent){if(K.cN){D+=""}}return{r:H,value:D,language:S,top:I}}catch(O){if(O.message.indexOf("Illegal")!=-1){return{r:0,value:j(L)}}else{throw O}}}function e(y,x){x=x||b.languages||Object.keys(f);var v={r:0,value:j(y)};var w=v;x.forEach(function(z){if(!i(z)){return}var A=c(z,y,false);A.language=z;if(A.r>w.r){w=A}if(A.r>v.r){w=v;v=A}});if(w.language){v.second_best=w}return v}function g(v){if(b.tabReplace){v=v.replace(/^((<[^>]+>|\t)+)/gm,function(w,z,y,x){return z.replace(/\t/g,b.tabReplace)})}if(b.useBR){v=v.replace(/\n/g,"
")}return v}function p(z){var y=b.useBR?z.innerHTML.replace(/\n/g,"").replace(/
|
]*>/g,"\n").replace(/<[^>]*>/g,""):z.textContent;var A=r(z);if(A=="no-highlight"){return}var v=A?c(A,y,true):e(y);var w=u(z);if(w.length){var x=document.createElementNS("http://www.w3.org/1999/xhtml","pre");x.innerHTML=v.value;v.value=q(w,u(x),y)}v.value=g(v.value);z.innerHTML=v.value;z.className+=" hljs "+(!A&&v.language||"");z.result={language:v.language,re:v.r};if(v.second_best){z.second_best={language:v.second_best.language,re:v.second_best.r}}}var b={classPrefix:"hljs-",tabReplace:null,useBR:false,languages:undefined};function s(v){b=o(b,v)}function l(){if(l.called){return}l.called=true;var v=document.querySelectorAll("pre code");Array.prototype.forEach.call(v,p)}function a(){addEventListener("DOMContentLoaded",l,false);addEventListener("load",l,false)}var f={};var n={};function d(v,x){var w=f[v]=x(this);if(w.aliases){w.aliases.forEach(function(y){n[y]=v})}}function k(){return Object.keys(f)}function i(v){return f[v]||f[n[v]]}this.highlight=c;this.highlightAuto=e;this.fixMarkup=g;this.highlightBlock=p;this.configure=s;this.initHighlighting=l;this.initHighlightingOnLoad=a;this.registerLanguage=d;this.listLanguages=k;this.getLanguage=i;this.inherit=o;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE]};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE]};this.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/};this.CLCM={cN:"comment",b:"//",e:"$",c:[this.PWM]};this.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[this.PWM]};this.HCM={cN:"comment",b:"#",e:"$",c:[this.PWM]};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.CSSNM={cN:"number",b:this.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0};this.RM={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.TM={cN:"title",b:this.IR,r:0};this.UTM={cN:"title",b:this.UIR,r:0}}();hljs.registerLanguage("javascript",function(a){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document"},c:[{cN:"pi",b:/^\s*('|")use strict('|")/,r:10},a.ASM,a.QSM,a.CLCM,a.CBCM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBCM,a.RM,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:true,c:[a.inherit(a.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+a.IR,r:0}]}}); \ No newline at end of file diff --git a/html/index.html b/html/index.html deleted file mode 100644 index d80959b..0000000 --- a/html/index.html +++ /dev/null @@ -1,2310 +0,0 @@ - - - -asm.js - - - - - - - - - -
-

asm.js

- -

Working Draft — 18 August 2014

- -
-
Latest version: -
http://asmjs.org/spec/latest/ - -
Editors: -
- David Herman, - Mozilla, - -
- Luke Wagner, - Mozilla, - -
- Alon Zakai, - Mozilla, - -
-
- -

Abstract

- -

This specification defines asm.js, a strict subset -of JavaScript that can be used as a low-level, efficient target -language for compilers. This sublanguage effectively describes a sandboxed -virtual machine for memory-unsafe languages like C or C++. A -combination of static and dynamic validation allows JavaScript engines -to employ an ahead-of-time (AOT) optimizing compilation strategy for -valid asm.js code. - -

Status

- -

This specification is working towards a candidate draft for asm.js -version 1. Mozilla's SpiderMonkey JavaScript engine provides an -optimizing implementation of this draft. - -

Changelog

- -
    -
  • 18 August 2014 -
      -
    • better "putting it all together" example -
    -
  • 23 July 2014 -
      -
    • formatting cleanups -
    • added variadic function types to the Global Types section -
    -
  • 22 July 2014 -
      -
    • clarified formal structure with explicit validation rule names -
    • moved function table validation from annotations section to validation section -
    • separated case and default validation rules -
    • eliminated unused expected case type parameter -
    • corrected type checks to subtype checks in AdditiveExpression, BitwiseXORExpression, BitwiseANDExpression, BitwiseORExpression, and ConditionalExpression -
    -
  • 8 July 2014 -
      -
    • minor editorial bugfixes -
    • non-function foreign imports are mut -
    • tightened the language on linking restrictions -
    -
  • 7 July 2014 -
      -
    • added 32-bit floating point types -
    • renamed doublish to double? for symmetry with float? -
    • separated heap access checking into a separate validation section -
    • separated load and store types for heap views -
    • added Math.fround and singleton fround type -
    • added a Float Coercions section -
    • added uncoerced CallExpression nodes to Expression for float coercions -
    • added float coercions to initializers, return type annotations, and legal function calls -
    • added restriction preventing float coercions of FFI calls -
    • added float support for operators and Math functions -
    • added float to legal result types for ConditionalExpression -
    • added variadic Math.min and Math.max -
    • eliminated the allowance for 1-byte views to elide their index shift (to future-proof for large heaps) -
    • simplified and generalized link-time restrictions on heap size -
    -
  • 12 December 2013 -
      -
    • return type of Math.abs is signed -
    -
  • 11 October 2013 -
      -
    • unsigned is not an extern type -
    • added missing ! operator to UnaryExpression operators -
    • added note about ~~ to Unary Operators section -
    • added note about parenthesis agnosticism to Syntax section -
    • added note about ASI to Syntax section -
    • added -NumericLiteral cases everywhere -
    • function calls require explicit coercions -
    • eliminated type unknown, which is no longer needed -
    • return type of integer % is intish -
    -
- -

Table of Contents

- - - -
    -
  1. 1 Introduction
  2. -
  3. 2 Types -
      -
    1. 2.1 Value Types -
        -
      1. 2.1.1 void
      2. -
      3. 2.1.2 double
      4. -
      5. 2.1.3 signed
      6. -
      7. 2.1.4 unsigned
      8. -
      9. 2.1.5 int
      10. -
      11. 2.1.6 fixnum
      12. -
      13. 2.1.7 intish
      14. -
      15. 2.1.8 double?
      16. -
      17. 2.1.9 float
      18. -
      19. 2.1.10 float?
      20. -
      21. 2.1.11 floatish
      22. -
      23. 2.1.12 extern
    2. -
    3. 2.2 Global Types
  4. -
  5. 3 Environments -
      -
    1. 3.1 Global Environment
    2. -
    3. 3.2 Variable Environment
    4. -
    5. 3.3 Environment Lookup
  6. -
  7. 4 Syntax
  8. -
  9. 5 Annotations -
      -
    1. 5.1 Parameter Type Annotations
    2. -
    3. 5.2 Return Type Annotations
    4. -
    5. 5.3 Function Type Annotations
    6. -
    7. 5.4 Variable Type Annotations
    8. -
    9. 5.5 Global Variable Type Annotations
    10. -
    11. 5.6 Function Table Types
  10. -
  11. 6 Validation Rules -
      -
    1. 6.1 ValidateModule(f)
    2. -
    3. 6.2 ValidateExport(Δ, s)
    4. -
    5. 6.3 ValidateFunctionTable(Δ, s)
    6. -
    7. 6.4 ValidateFunction(Δ, f)
    8. -
    9. 6.5 ValidateStatement(Δ, Γ, τ, s) -
        -
      1. 6.5.1 Block
      2. -
      3. 6.5.2 ExpressionStatement
      4. -
      5. 6.5.3 EmptyStatement
      6. -
      7. 6.5.4 IfStatement
      8. -
      9. 6.5.5 ReturnStatement
      10. -
      11. 6.5.6 IterationStatement
      12. -
      13. 6.5.7 BreakStatement
      14. -
      15. 6.5.8 ContinueStatement
      16. -
      17. 6.5.9 LabelledStatement
      18. -
      19. 6.5.10 SwitchStatement
    10. -
    11. 6.6 ValidateCase(Δ, Γ, τ, c)
    12. -
    13. 6.7 ValidateDefault(Δ, Γ, τ, d)
    14. -
    15. 6.8 ValidateExpression(Δ, Γ, e) -
        -
      1. 6.8.1 Expression
      2. -
      3. 6.8.2 NumericLiteral
      4. -
      5. 6.8.3 Identifier
      6. -
      7. 6.8.4 CallExpression
      8. -
      9. 6.8.5 MemberExpression
      10. -
      11. 6.8.6 AssignmentExpression
      12. -
      13. 6.8.7 UnaryExpression
      14. -
      15. 6.8.8 MultiplicativeExpression
      16. -
      17. 6.8.9 AdditiveExpression
      18. -
      19. 6.8.10 ShiftExpression
      20. -
      21. 6.8.11 RelationalExpression
      22. -
      23. 6.8.12 EqualityExpression
      24. -
      25. 6.8.13 BitwiseANDExpression
      26. -
      27. 6.8.14 BitwiseXORExpression
      28. -
      29. 6.8.15 BitwiseORExpression
      30. -
      31. 6.8.16 ConditionalExpression
      32. -
      33. 6.8.17 Parenthesized Expression
    16. -
    17. 6.9 ValidateCall(Δ, Γ, τ, e)
    18. -
    19. 6.10 ValidateHeapAccess(Δ, Γ, e)
    20. -
    21. 6.11 ValidateFloatCoercion(Δ, Γ, e)
  12. -
  13. 7 Linking
  14. -
  15. 8 Operators -
      -
    1. 8.1 Unary Operators
    2. -
    3. 8.2 Binary Operators
  16. -
  17. 9 Standard Library
  18. -
  19. 10 Heap View Types
  20. -
  21. Acknowledgements
- - -

1 Introduction

- -

This specification defines asm.js, a strict subset of -JavaScript that can be used as a low-level, efficient target language -for compilers. The asm.js language provides an abstraction similar to -the C/C++ virtual machine: a large binary heap with efficient loads -and stores, integer and floating-point arithmetic, first-order -function definitions, and function pointers. - -

Programming Model

- -

The asm.js programming model is built around integer and -floating-point arithmetic and a virtual heap represented as -a typed -array. While JavaScript does not directly provide constructs for -dealing with integers, they can be emulated using two tricks: - -

    -
  • integer loads and stores can be performed using the typed arrays -API; and -
  • integer arithmetic is equivalent to the composition of -JavaScript's floating-point arithmetic operators with the integer -coercions performed by the bitwise operators. -
- -

As an example of the former, if we have -an Int32Array -view of the heap called HEAP32, then we can load the -32-bit integer at byte offset p: - - - -

-
HEAP32[p >> 2]|0
-
- -

The shift converts the byte offset to a 32-bit element offset, and -the bitwise coercion ensures that an out-of-bounds access is coerced -from undefined back to an integer. - - - -

As an example of integer arithmetic, addition can be performed by -taking two integer values, adding them with the built-in addition -operator, and coercing the result back to an integer via the bitwise -or operator: - -

-
(x+y)|0
-
- -

This programming model is directly inspired by the techniques -pioneered by the Emscripten -and Mandreel compilers. - -

Validation

- -

The asm.js sub-language is defined by a -static type system that can be checked -at JavaScript parse time. Validation of asm.js code is designed to be -"pay-as-you-go" in that it is never performed on code that does not -request it. An asm.js module requests validation by means -of a -special prologue -directive, similar to that of ECMAScript Edition -5's strict -mode: - -

-
function MyAsmModule() {
-    "use asm";
-    // module body
-}
-
- -

This explicit directive allows JavaScript engines to avoid -performing pointless and potentially costly validation on other -JavaScript code, and to report validation errors in developer consoles -only where relevant. - -

Ahead-Of-Time Compilation

- -

Because asm.js is a strict subset of JavaScript, this specification -only defines the validation logic—the execution semantics is -simply that of JavaScript. However, validated asm.js is amenable to -ahead-of-time (AOT) compilation. Moreover, the code generated by an -AOT compiler can be quite efficient, featuring: - -

    -
  • unboxed representations of integers and floating-point numbers; -
  • absence of runtime type checks; -
  • absence of garbage collection; and -
  • efficient heap loads and stores (with implementation strategies varying by platform). -
- -

Code that fails to validate must fall back to execution by -traditional means, e.g., interpretation and/or just-in-time (JIT) -compilation. - - - -

Linking

- -

Using an asm.js module requires calling its function to obtain an -object containing the module's exports; this is known -as linking. An asm.js module can also be given access to -standard libraries and custom JavaScript functions through linking. An -AOT implementation must perform certain dynamic -checks to check compile-time assumptions about the linked -libraries in order to make use of the compiled code. - -

This figure depicts a simple architecture of an AOT implementation -that otherwise employs a simple interpreter. If either dynamic or -static validation fails, the implementation must fall back to the -interpreter. But if both validations succeed, calling the module -exports executes the binary executable code generated by AOT -compilation. - -

- -
- -

External Code and Data

- -

Within an asm.js module, all code is fully statically typed and -limited to the very restrictive asm.js dialect. However, it is -possible to interact with recognized standard JavaScript libraries and -even custom dynamic JavaScript functions. - -

An asm.js module can take up to three optional parameters, -providing access to external JavaScript code and data: - -

    -
  • a standard library object, providing access to a -limited subset of the JavaScript standard -libraries; -
  • a foreign function interface (FFI), providing access to -custom external JavaScript functions; and -
  • a heap buffer, providing a -single ArrayBuffer -to act as the asm.js heap. -
- -

These objects allow asm.js to call into external JavaScript (and to -share its heap buffer with external JavaScript). Conversely, the -exports object returned from the module allows external JavaScript to -call into asm.js. - -

So in the general case, an asm.js module declaration looks like: - -

-
function MyAsmModule(stdlib, foreign, heap) {
-    "use asm";
-
-    // module body...
-
-    return {
-        export1: f1,
-        export2: f2,
-        // ...
-    };
-}
-
- -

Function parameters in asm.js are provided a type annotation by -means of an explicit coercion on function entry: - -

-
function geometricMean(start, end) {
-  start = start|0; // start has type int
-  end = end|0;     // end has type int
-  return +exp(+logSum(start, end) / +((end - start)|0));
-}
- -
- -

These annotations serve two purposes: first, to provide the -function's type signature so that the validator can enforce that all -calls to the function are well-typed; second, to ensure that even if -the function is exported and called by external JavaScript, its -arguments are dynamically coerced to the expected type. This ensures -that an AOT implementation can use unboxed value representations, -knowing that once the dynamic coercions have completed, the function -body never needs any runtime type checks. - -

Putting It All Together

- -

The following is a small but complete example of an asm.js module. - -

-
function GeometricMean(stdlib, foreign, buffer) {
-  "use asm";
-
-  var exp = stdlib.Math.exp;
-  var log = stdlib.Math.log;
-  var values = new stdlib.Float64Array(buffer);
-
-  function logSum(start, end) {
-    start = start|0;
-    end = end|0;
-
-    var sum = 0.0, p = 0, q = 0;
-
-    // asm.js forces byte addressing of the heap by requiring shifting by 3
-    for (p = start << 3, q = end << 3; (p|0) < (q|0); p = (p + 8)|0) {
-      sum = sum + +log(values[p>>3]);
-    }
-
-    return +sum;
-  }
-
-  function geometricMean(start, end) {
-    start = start|0;
-    end = end|0;
-
-    return +exp(+logSum(start, end) / +((end - start)|0));
-  }
-
-  return { geometricMean: geometricMean };
-}
-
- -

In a JavaScript engine that supports AOT compilation of asm.js, -calling the module on a proper global object and heap buffer would -link the exports object to use the statically compiled functions. - -

-
var heap = new ArrayBuffer(0x10000);          // 64k heap
-init(heap, START, END);                       // fill a region with input values
-var fast = GeometricMean(window, null, heap); // produce exports object linked to AOT-compiled code
-fast.geometricMean(START, END);               // computes geometric mean of input values
-
- -

By contrast, calling the module on a standard library object -containing something other than the true Math.exp or -Math.log would fail to produce AOT-compiled code: - -

-
var bogusGlobal = {
-  Math: {
-    exp: function(x) { return x; },
-    log: function(x) { return x; }
-  },
-  Float64Array: Float64Array
-};
-
-var slow = GeometricMean(bogusGlobal, null, heap); // produces purely-interpreted/JITted version
-console.log(slow.geometricMean(START, END));       // computes bizarro-geometric mean thanks to bogusGlobal
-
- - - -

2 Types

- -

Validation of an asm.js module relies on a static type system that -classifies and constrains the syntax. This section defines the types -used by the validation logic. - -

2.1 Value Types

- -

Validation in asm.js limits JavaScript programs to only use operations -that can be mapped closely to efficient data representations and -machine operations of modern architectures, such as 32-bit integers -and integer arithmetic. - -

The types of asm.js values are inter-related by a subtyping -relation, which can be represented pictorially: - -

- -
- -

The light boxes represent arbitrary JavaScript values that may flow -freely between asm.js code and external JavaScript code. - -

The dark boxes represent types that are disallowed from escaping -into external (i.e., non-asm.js) JavaScript code. (These values can be -given efficient, unboxed representations in optimized asm.js -implementations that would be unsound if they were allowed to escape.) - -

The meta-variables σ and τ are used to stand for value -types. - -

2.1.1 void

- -

The void type is the type of functions that -are not supposed to return any useful value. As JavaScript functions, -they produce the undefined value, but asm.js code is not -allowed to make use of this value; functions with return -type void can only be called for effect. - -

2.1.2 double

- -

The double type is the type of ordinary -JavaScript double-precision floating-point numbers. - -

2.1.3 signed

- -

The signed type is the type of signed -32-bit integers. While there is no direct concept of integers in -JavaScript, 32-bit integers can be represented as doubles, and integer -operations can be performed with JavaScript arithmetic, relational, -and bitwise operators. - -

2.1.4 unsigned

- -

The unsigned type is the type of unsigned -32-bit integers. Again, these are not a first-class concept in -JavaScript, but can be represented as floating-point numbers. - -

2.1.5 int

- -

The int type is the type of 32-bit integers -where the signedness is not known. In asm.js, the type of a variable -never has a known signedness. This allows them to be compiled as -32-bit integer registers and memory words. However, this -representation creates an overlap between signed and unsigned numbers -that causes an ambiguity in determining which JavaScript number they -represent. For example, the bit pattern 0xffffffff could -represent 4294967295 or -1, depending on the signedness. For this -reason, values of the int type are disallowed from -escaping into external (non-asm.js) JavaScript code. - -

2.1.6 fixnum

- -

The fixnum type is the type of integers in the -range [0, 231)—that is, the range of integers such -that an unboxed 32-bit representation has the same value whether it is -interpreted as signed or unsigned. - - -

2.1.7 intish

- -

Even though JavaScript only supports floating-point arithmetic, -most operations can simulate integer arithmetic by coercing their -result to an integer. For example, adding two integers may overflow -beyond the 32-bit range, but coercing the result back to an integer -produces the same 32-bit integer as integer addition in, say, C. - -

The intish type represents the result of a -JavaScript integer operation that must be coerced back to an integer -with an explicit coercion -(ToInt32 -for signed integers -and ToUint32 -for unsigned integers). Validation requires all intish -values to be immediately passed to an operator or standard library -that performs the appropriate coercion or else dropped via an -expression statement. This way, each integer operation can be -compiled directly to machine operations. - -

The one operator that does not support this approach is -multiplication. (Multiplying two large integers can result in a large -enough double that some lower bits of precision are lost.) So asm.js -does not support applying the multiplication operator to integer -operands. Instead, the -proposed Math.imul -function is recommended as the proper means of implementing integer -multiplication. - - -

2.1.8 double?

- -

The double? type represents operations that -are expected to produce a double but may also produce -undefined, and so must be coerced back to a number -via ToNumber. -Specifically, reading out of bounds from a typed array -produces undefined. - -

2.1.9 float

- -

The float type is the type of 32-bit -floating-point numbers. - -

2.1.10 float?

- -

The float? type represents operations that -are expected to produce a float but, similar -to double?, may also produce undefined and -so must be coerced back to a 32-bit floating point number -via fround. -Specifically, reading out of bounds from a typed array -produces undefined. - -

2.1.11 floatish

- -

Similar to integers, JavaScript can almost support 32-bit -floating-point arithmetic, but requires extra coercions to properly -emulate the 32-bit semantics. As proved in -When is double -rounding innocuous? (Figueroa 1995), both the 32- and 64-bit -versions of standard arithmetic operations produce equivalent results -when given 32-bit inputs and coerced to 32-bit outputs. - -

The floatish type, -like intish, represents the result of a JavaScript 32-bit -floating-point operations that must be coerced back to a 32-bit -floating-point value with an -explicit fround -coercion. Validation requires all floatish values to be -immediately passed to an operator or standard library that performs -the appropriate coercion or else dropped via an expression -statement. This way, each 32-bit floating-point operation can be -compiled -directly to machine operations. - -

2.1.12 extern

- -The abstract extern type represents the root -of all types that can escape back into external JavaScript—in -other words, the light boxes in the above diagram. - -

2.2 Global Types

- -

Variables and functions defined at the top-level scope of an asm.js -module can have additional types beyond -the value types. These include: - -

    -
  • value types τ; -
  • ArrayBufferView types IntnArray, UintnArray, and FloatnArray; -
  • function types ((σ, …) → τ) ∧ … ∧ ((σ′, …) → τ′); -
  • variadic function types ((σ, σ) → τ) ∧ … ∧ ((σ′, σ′) → τ′); -
  • function table types ((σ, …) → τ)[n]; -
  • the special type fround of Math.fround; and -
  • the FFI function type Function. -
- -

The "∧" notation for function types serves to represent -overloaded functions and operators. For example, -the Math.abs function is -overloaded to accept either integers or floating-point numbers, and -returns a different type in each case. Similarly, many of -the operators have overloaded types. - -

The meta-variable γ is used to stand for global types. - -

3 Environments

- -

Validating an asm.js module depends on tracking contextual -information about the set of definitions and variables in scope. This -section defines the environments used by the validation -logic. - -

3.1 Global Environment

- -

An asm.js module is validated in the context of a global -environment. The global environment maps each global variable to -its type as well as indicating whether the variable is mutable: - -

{ x : (mut|imm) γ, … }
- -

The meta-variable Δ is used to stand for a global environment. - -

3.2 Variable Environment

- -

In addition to the global environment, each function -body in an asm.js module is validated in the context of -a variable environment. The variable environment maps each -function parameter and local variable to its value type: - -

{ x : τ, … } - -

The meta-variable Γ is used to stand for a variable environment. - -

3.3 Environment Lookup

- -

Looking up a variable's type - -

-Lookup(Δ, Γ, x) -
- -

is defined by: - -

    -
  • τ if x : τ occurs in Γ; -
  • γ if x does not occur in Γ and x -: mut γ or x : imm γ -occurs in Δ -
- -

If x does not occur in either environment then -the Lookup function has no result. - -

4 Syntax

- -

Validation of an asm.js module is specified by reference to -the ECMAScript -grammar, but conceptually operates at the level of abstract -syntax. In particular, an asm.js validator must obey the following -rules: - -

    -
  • Empty statements (;) are always ignored, whether in -the top level of a module or inside an asm.js function body. -
  • No variables bound anywhere in an asm.js module (whether in the -module function parameter list, global variable declarations, asm.js -function names, asm.js function parameters, or local variable -declarations) may have the name eval -or arguments. -
  • Where it would otherwise parse equivalently in JavaScript, -parentheses are meaningless. Even where the specification matches on -specific productions of Expression such as literals, the -source may contain extra meaningless parentheses without affecting -validation. -
  • Automatic semicolon insertion is respected. An asm.js source file -may omit semicolons wherever JavaScript allows them to be omitted. -
- -

These rules are otherwise left implicit in the rest of the -specification. - -

5 Annotations

- -

All variables in asm.js are explicitly annotated with type -information so that their type can be statically enforced by -validation. - -

5.1 Parameter Type Annotations

- -

Every parameter in an asm.js function is provided with an explicit -type annotation in the form of a coercion. This coercion serves two -purposes: the first is to make the parameter type statically apparent -for validation; the second is to ensure that if the function is -exported, the arguments dynamically provided by external JavaScript -callers are coerced to the expected type. For example, a bitwise OR -coercion annotates a parameter as having type int: - -

-
function add1(x) {
-    x = x|0; // x : int
-    return (x+1)|0;
-}
-
- -

In an AOT implementation, the body of the function can be -implemented fully optimized, and the function can be given two entry -points: an internal entry point for asm.js callers, which are -statically known to provide the proper type, and an external dynamic -entry point for JavaScript callers, which must perform the full -coercions (which might involve arbitrary JavaScript computation, e.g., -via implicit calls to valueOf). - -

There are three recognized parameter type annotations: - -

-x:Identifier = x:Identifier|0;
-x:Identifier = +x:Identifier;
-x:Identifier = f:Identifier(x:Identifier); -
- -

The first form annotates a parameter as type int, the -second as type double, and the third as -type float. In the latter case, -Lookup(Δ, Γ, f) must -be fround. - -

5.2 Return Type Annotations

- -

An asm.js function's formal return type is determined by -the last statement in the function body, which for -non-void functions is required to be -a ReturnStatement. This distinguished return statement may -take one of five forms: - -

-return +e:Expression;
-return e:Expression|0;
-return n:-?NumericLiteral;
-return f:Identifier(arg:Expression);
-return; -
- -

The first form has return type double. The second has -type signed. The third has return -type double if n is composed of a floating-point -literal, i.e., a numeric literal with the character . in -its source; alternatively, if n is composed of an integer -literal and has its value in the range [-231, -231), the return statement has return -type signed. The fourth form has return -type float, and the fifth has return -type void. - -

If the last statement in the function body is not -a ReturnStatement, or if the function body has no non-empty -statements (other than the initial declarations and -coercions—see Function -Declarations), the function's return type is void. - -

5.3 Function Type Annotations

- -

The type of a function declaration - -

-function f:Identifier(x:Identifier) {
-    (x:Identifier = AssignmentExpression;)
-    (var (y:Identifier = (-?NumericLiteral | Identifier(-?NumericLiteral))),)
-    body:Statement
-} -
- -

is (σ,…) → τ where σ,… are the -types of the parameters, as provided by -the parameter type -annotations, and τ is the formal return type, as provided by -the return type annotation. The -variable f is stored in -the global environment with -type imm (σ,…) → τ. - -

5.4 Variable Type Annotations

- -

The types of variable declarations are determined by their -initializer, which may take one of two forms: - -

-n:-?NumericLiteral
-f:Identifier(n:-?NumericLiteral) - -
- -

In the first case, the variable type is double -if n's source contains the character .; -otherwise n may be an integer literal in the range -[-231, 232), in which case the variable type -is int. - -

In the second case, the variable type -is float. Lookup(Δ, Γ, f) -must be fround and n must be a floating-point -literal with the character . in its source. - - - -

5.5 Global Variable Type Annotations

- -

A global variable declaration is a VariableStatement node -in one of several allowed forms. Validating global variable -annotations takes a Δ as input and produces as output a new -Δ′ by adding the variable binding to Δ. - -

A global program variable is initialized to a literal: - -

-var x:Identifier = n:-?NumericLiteral;
-var x:Identifier = f:Identifier(n:-?NumericLiteral); -
- -

The global variable x is stored in -the global environment with -type mut τ, where τ is determined in the same way -as local variable type -annotations. - -

A standard library import is of one of the following two forms: - -

-var x:Identifier = stdlib:Identifier.y:Identifier;
-var x:Identifier = stdlib:Identifier.Math.y:Identifier; -
- -

The variable stdlib must match the first parameter of -the module declaration. The global -variable x is stored in -the global environment with -type imm γ, where γ is the type of -library y or Math.y as specified by -the standard library types. - -

A foreign import is of one of the following three forms: - -

-var x:Identifier = foreign:Identifier.y:Identifier;
-var x:Identifier = foreign:Identifier.y:Identifier|0;
-var x:Identifier = +foreign:Identifier.y:Identifier; -
- -

The variable foreign must match the second parameter of -the module declaration. The global -variable x is stored in -the global environment with -type imm Function for the first form, mut -int for the second, and mut double for the third. - -

A global heap view is of the following form: - -

-var x:Identifier = new stdlib:Identifier.view:Identifier(heap:Identifier); -
- -

The variable stdlib must match the first parameter of -the module declaration and the -variable heap must match the third. The -identifier view must be one of the -standard ArrayBufferView -type names. The global variable x is stored in -the global environment with -type imm -view. - -

5.6 Function Table Types

- -

A function table is a VariableStatement of the form: - -

-var x:Identifier = [f0:Identifier, f:Identifier,]; -
- -

The function table x is stored in -the global environment with -type imm ((σ,…) → τ)[n] -where (σ,…) → τ is the type of f in the -global environment and n is the length of the array literal. - - - -

6 Validation Rules

- -

To ensure that a JavaScript function is a proper asm.js module, it -must first be statically validated. This section specifies the -validation rules. The rules operate on JavaScript abstract syntax, -i.e., the output of a JavaScript parser. The non-terminals refer to -parse nodes defined by productions in -the ECMAScript -grammar, but note that the asm.js validator only accepts a subset -of legal JavaScript programs. - -

The result of a validation operation is either -a success, indicating that a parse node is statically valid -asm.js, or a failure, indicating that the parse node is -statically invalid asm.js. - -

6.1 ValidateModule(f)

- -

The ValidateModule rule validates an asm.js module, which -is either a FunctionDeclaration -or FunctionExpression node. - -

Validating a module of the form - -

-function f:Identifieropt((stdlib:Identifier(, foreign:Identifier(, heap:Identifier)opt)opt)opt) {
-    "use asm";

-    var:VariableStatement
-    fun:FunctionDeclaration
- -    table:VariableStatement
-    exports:ReturnStatement
-} -
- -

succeeds if: - -

    -
  • f, stdlib, foreign, heap, and -the var, fun, and table variables are all -mutually distinct; -
  • the global environment Δ is constructed in three stages: -
      -
    1. the global declarations are - validated in an empty initial environment Δ0, - producing a new global environment Δ1; -
    2. the types from the function - type annotations in the fun declarations are extracted - using Δ1, and then added to Δ1 to - produce Δ2; - -
    3. the types of the function - tables in the table declarations are extracted - using Δ2, and their types are added to - Δ2 to produce the completed global type environment - Δ. -
    -
  • for each fun declaration, ValidateFunction succeeds with environment Δ; -
  • for each table declaration, ValidateFunctionTable succeeds with environment Δ; and -
  • ValidateExport succeeds for exports with environment Δ. -
- - -

6.2 ValidateExport(Δ, s)

- -

The ValidateExport rule validates an asm.js module's -export declaration. An export declaration is -a ReturnStatement returning either a single asm.js function -or an object literal exporting multiple asm.js functions. - -

Validating an export declaration node - -

-return { (x:Identifier : f:Identifier), }; -
- -

succeeds if for each f, Δ(f) = imm -γ where γ is a function type (σ,…) → -τ. - -

Validating an export declaration node - -

-return f:Identifier; -
- -

succeeds if Δ(f) = imm γ where -γ is a function type (σ,…) → τ. - -

6.3 ValidateFunctionTable(Δ, s)

- -

The ValidateFunctionTable rule validates an asm.js -module's function table declaration. A function table declaration is -a VariableStatement binding an identifier to an array -literal. - -

Validating a function table of the form - -

-var x:Identifier = [f:Identifier,]; -
- -

succeeds if: - -

    -
  • the length n of the array literal is 2m for some m ≥ 0; -
  • Δ(x) = imm ((σ,…) → τ)[n]; and -
  • for each f, Δ(f) = (σ,…) → τ. -
- - -

6.4 ValidateFunction(Δ, f)

- -

The ValidateFunction rule validates an asm.js function -declaration, which is a FunctionDeclaration node. - -

Validating a function declaration of the form - -

-function f:Identifier(x:Identifier,) {
-    (x:Identifier = AssignmentExpression;)
-    (var (y:Identifier = (-?NumericLiteral | Identifier(-?NumericLiteral))),)
-    body:Statement
-} -
- -

succeeds if: - -

    -
  • Δ(f) = imm (σ,…) → τ; -
  • the x and y variables are all mutually distinct; -
  • the variable environment Γ is constructed by mapping each -parameter x to its -corresponding parameter type -annotation (annotations must appear in the same order as the -parameters) and each local variable y to -its variable type annotation; -
  • for each body -statement, ValidateStatement -succeeds with environments Δ and Γ and expected return -type τ. -
- -

6.5 ValidateStatement(Δ, Γ, τ, s)

- -

The ValidateStatement rule validates an asm.js statement. -Each statement is validated in the context of a global -environment Δ, a variable environment -Γ, and an expected return type τ. Unless otherwise -explicitly stated, a recursive validation of a subterm uses the same -context as its containing term. - -

6.5.1 Block

- -

Validating a Block statement node - -

-{ stmt:Statement} -
- -

succeeds -if ValidateStatement -succeeds for each stmt. - -

6.5.2 ExpressionStatement

- -

Validating an ExpressionStatement node - -

-cexpr:CallExpression ; -
- -

succeeds if ValidateCall -succeeds for cexpr with actual return type void. - -

Validating an ExpressionStatement node - -

-expr:Expression ; -
- -

succeeds -if ValidateExpression -succeeds for expr with some type σ. - -

6.5.3 EmptyStatement

- -

Validating an EmptyStatement node always succeeds. - -

6.5.4 IfStatement

- -

Validating an IfStatement node - -

-if ( expr:Expression ) stmt1:Statement else stmt2:Statement -
- -

succeeds -if ValidateExpression -succeeds for expr with a subtype of int -and ValidateStatement -succeeds for stmt1 and stmt2. - -

Validating an IfStatement node - -

-if ( expr:Expression ) stmt:Statement -
- -

succeeds -if ValidateExpression -succeeds for expr with a subtype of int -and ValidateStatement -succeeds for stmt. - -

6.5.5 ReturnStatement

- -

Validating a ReturnStatement node - -

-return expr:Expression ; -
- -

succeeds -if ValidateExpression -succeeds for expr with a subtype of the expected return type -τ. - -

Validating a ReturnStatement node - -

-return ; -
- -

succeeds if the expected return type τ is void. - - -

6.5.6 IterationStatement

- -

Validating an IterationStatement node - -

-while ( expr:Expression ) stmt:Statement -
- -

succeeds -if ValidateExpression -succeeds for expr with a subtype of int -and ValidateStatement -succeeds for stmt. - -

Validating an IterationStatement node - -

-do stmt:Statement while ( expr:Expression ) ; -
- -

succeeds -if ValidateStatement -succeeds for stmt -and ValidateExpression -succeeds for expr with a subtype of int. - -

Validate an IterationStatement node - -

-for ( init:ExpressionNoInopt ; test:Expressionopt ; update:Expressionopt ) body:Statement -
- -

succeeds if: - -

- -

6.5.7 BreakStatement

- -

Validating a BreakStatement node - -

-break Identifieropt ; -
- -

always succeeds. - -

6.5.8 ContinueStatement

- -

Validating a ContinueStatement node - -

-continue Identifieropt ; -
- -

always succeeds. - -

6.5.9 LabelledStatement

- -

Validating a LabelledStatement node - -

-Identifier : body:Statement -
- -

succeeds -if ValidateStatement -succeeds for body. - -

6.5.10 SwitchStatement

- -

Validating a SwitchStatement node - -

-switch ( test:Expression ) { case:CaseClausedefault:DefaultClauseopt } -
- -

succeeds if - -

    -
  • ValidateExpression succeeds for test with a subtype of signed; -
  • ValidateCase succeeds for each case; -
  • each case value is distinct; -
  • the difference between the maximum and minimum case values is less than 231; and -
  • ValidateDefault succeeds for default. -
- - - - - - -

6.6 ValidateCase(Δ, Γ, τ, c)

- -

Cases in a switch block are validated in the context -of a global environment Δ, a variable -environment Γ, and an expected return type τ. Unless -otherwise explicitly stated, a recursive validation of a subterm uses -the same context as its containing term. - - - - - - - -

Validating a CaseClause node - -

-case n:-?NumericLiteral : stmt:Statement… -
- -

succeeds if - -

    -
  • the source of n does not contain a . character; -
  • n is in the range [-231, 231); and -
  • ValidateStatement succeeds for each stmt. -
- -

6.7 ValidateDefault(Δ, Γ, τ, d)

- -

The default case in a switch block is validated in the -context of a global environment Δ, a variable -environment Γ, and an expected return type τ. Unless -otherwise explicitly stated, a recursive validation of a subterm uses -the same context as its containing term. - - - -

Validating a DefaultClause node - -

-default : stmt:Statement… -
- -

succeeds -if ValidateStatement -succeeds for each stmt. - - -

6.8 ValidateExpression(Δ, Γ, e)

- -

Each expression is validated in the context of a global -environment Δ and a variable environment -Γ, and validation produces the type of the expression as a -result. Unless otherwise explicitly stated, a recursive validation of -a subterm uses the same context as its containing term. - -

6.8.1 Expression

- -

Validating an Expression node - -

-expr1:AssignmentExpression ,, exprn:AssignmentExpression -
- -

succeeds with type τ if for every i -< n, one of the following conditions holds: - -

- -

and ValidateExpression -succeeds for exprn with type τ. - -

6.8.2 NumericLiteral

- -

Validating a NumericLiteral node - -

    -
  • succeeds with type double if the source contains a . character; or -validates as type double; -
  • succeeds with type fixnum if the source does not contain a . character and its numeric value is in the range [0, 231); or -
  • succeeds with type unsigned if the source does not contain a . character and its numeric value is in the range [231, 232). -
- -

Note that the case of negative integer constants is handled -under UnaryExpression. - -

Note that integer literals outside the range [0, 232) -are invalid, i.e., fail to validate. - -

6.8.3 Identifier

- -

Validating an Identifier node - -

-x:Identifier -
- -

succeeds with type τ if Lookup(Δ, Γ, x) = τ. - -

6.8.4 CallExpression

- -

Validating a CallExpression node succeeds with -type float -if ValidateFloatCoercion -succeeds. - -

6.8.5 MemberExpression

- -

Validating a MemberExpression node succeeds with type -τ -if ValidateHeapAccess -succeeds with load type τ. - -

6.8.6 AssignmentExpression

- -

Validating an AssignmentExpression node - -

-x:Identifier = expr:AssignmentExpression -
- -

succeeds with type τ -if ValidateExpression -succeeds for the nested AssignmentExpression with type τ -and one of the following two conditions holds: - -

    -
  • x is bound in Γ as a supertype of τ; or -
  • x is not bound in Γ and is bound to a mutable supertype of τ in Δ. -
- -

Validating an AssignmentExpression node - -

-lhs:MemberExpression = rhs:AssignmentExpression -
- -

succeeds with type τ -if ValidateExpression -succeeds for rhs with type τ -and ValidateHeapAccess -succeeds for lhs with τ as one of its legal store types. - - - -

6.8.7 UnaryExpression

- -

Validating a UnaryExpression node of the form - -

--NumericLiteral -
- -

succeeds with type signed if -the NumericLiteral source does not contain a . -character and the numeric value of the expression is in the range -[-231, 0). - -

Validating a UnaryExpression node of the form - -

-+cexpr:CallExpression -
- -

succeeds with type double -if ValidateCall succeeds -for cexpr with actual return type double. - -

Validating a UnaryExpression node of the form - -

-op:(+|-|~|!)arg:UnaryExpression -
- -

succeeds with type τ if the type of op is … -∧ (σ) → τ ∧ … -and ValidateExpression -succeeds with a subtype of σ. - -

Validating a UnaryExpression node of the form - -

-~~arg:UnaryExpression -
- -

succeeds with type signed -if ValidateExpression -succeeds for arg with a subtype of either double -or float?. - -

6.8.8 MultiplicativeExpression

- -

Validating a MultiplicativeExpression node - -

-lhs:MultiplicativeExpression op:(*|/|%) rhs:UnaryExpression -
- -

succeeds with type τ if: - -

- -

Validating a MultiplicativeExpression node - -

-expr:MultiplicativeExpression * n:-?NumericLiteral
-n:-?NumericLiteral * expr:UnaryExpression -
- -

succeeds with type intish if the source of n -does not contain a . character and -220 -< n < 220 -and ValidateExpressionexpr with a subtype of int. - -

6.8.9 AdditiveExpression

- -

Validating an AdditiveExpression node - -

-expr1 (+|-)(+|-) exprn -
- -

succeeds with type intish if: - -

- -

Otherwise, validating an AdditiveExpression node - -

-lhs:AdditiveExpression op:(+|-) rhs:MultiplicativeExpression -
- -

succeeds with type double if: - -

- -

6.8.10 ShiftExpression

- -

Validating a ShiftExpression node - -

-lhs:ShiftExpression op:(<<|>>|>>>) rhs:AdditiveExpression - -
- -

succeeds with type τ if - -

- -

6.8.11 RelationalExpression

- -

Validating a RelationalExpression node - -

-lhs:RelationalExpression op:(<|>|<=|>=) rhs:ShiftExpression - -
- -

succeeds with type τ if - -

- -

6.8.12 EqualityExpression

- -

Validating an EqualityExpression node - -

-lhs:EqualityExpression op:(==|!=) rhs:RelationalExpression - -
- -

succeeds with type τ if - -

- -

6.8.13 BitwiseANDExpression

- -

Validating a BitwiseANDExpression node - -

-lhs:BitwiseANDExpression & rhs:EqualityExpression
-
- -

succeeds with type signed -if ValidateExpression -succeeds for lhs and rhs with -a subtype of intish. - -

6.8.14 BitwiseXORExpression

- -

Validating a BitwiseXORExpression node - -

-lhs:BitwiseXORExpression ^ rhs:BitwiseANDExpression
-
- -

succeeds with type signed -if ValidateExpression -succeeds for lhs and rhs with -a subtype of intish. - -

6.8.15 BitwiseORExpression

- -

Validating a BitwiseORExpression node - -

-cexpr:CallExpression |0
-
- -

succeeds with type signed -if ValidateCall succeeds -for cexpr with actual return type signed. - -

Validating a BitwiseORExpression node - -

-lhs:BitwiseORExpression | rhs:BitwiseXORExpression
-
- -

succeeds with type signed -if ValidateExpression -succeeds for lhs and rhs with -a subtype of intish. - -

6.8.16 ConditionalExpression

- -

Validating a ConditionalExpression node - -

-test:BitwiseORExpression ? cons:AssignmentExpression : alt:AssignmentExpression -
- -

succeeds with type τ if: - -

- -

6.8.17 Parenthesized Expression

- -

Validating a parenthesized expression node - -

-( expr:Expression ) -
- -

succeeds with type τ -if ValidateExpression -succeeds for expr with type τ. - - -

6.9 ValidateCall(Δ, Γ, τ, e)

- -

Each function call expression is validated in the context of a -global environment Δ and a variable environment Γ, and -validates against an actual return type τ, which was -provided from the context in which the function call appears. A -recursive validation of a subterm uses the same context as its -containing term. - -

Validating a CallExpression node - -

-f:Identifier(arg:Expression,) -
- -

with actual return type τ succeeds if one of the following -conditions holds: - -

    -
  • ValidateFloatCoercion -succeeds for the node; -
  • Lookup(Δ, Γ, f) = … ∧ -(σ,…) → τ ∧ … -and ValidateExpression -succeeds for each arg with a subtype of its corresponding -σ; or -
  • Lookup(Δ, Γ, f) = … ∧ -(σ1,…,σn) -→ τ ∧ … -and ValidateExpression -succeeds for the first n argi expressions -with subtypes of their corresponding σi and -the remaining arg expressions with subtypes of σ. -
- -

Alternatively, validating the CallExpression succeeds with -any actual return type τ other than float -if Lookup(Δ, Γ, f) -= Function -and ValidateExpression -succeeds for each arg with a subtype of extern. - - - -

Validating a CallExpression node - -

-x:Identifier[index:Expression & n:-?NumericLiteral](arg:Expression,) -
- -

succeeds with actual return type τ if: - -

    -
  • the source of n does not contain a . character; -
  • Lookup(Δ, -Γ, x) = ((σ,…) → -τ)[n+1]; -
  • ValidateExpression -succeeds for index with a subtype of intish; and -
  • ValidateExpression -succeeds for each arg with a subtype of its corresponding -σ. -
- - - -

6.10 ValidateHeapAccess(Δ, Γ, e)

- -

Each heap access expression is validated in the context of a global -environment Δ and a variable environment Γ, and validation -produces a load type as well as a set of legal store -types as a result. These types are determined by -the heap view types corresponding to -each ArrayBufferView -type. - -

Validating a MemberExpression node - -

-x:Identifier[n:-?NumericLiteral] -
- -

succeeds with load type σ and store types { τ, … } if: - -

    -
  • Lookup(Δ, Γ, x) = view -where view is -an ArrayBufferView -type; -
  • the load type of view is σ; -
  • the store types of view are { τ, … }; -
  • the source of n does not contain a . character; -
  • 0 ≤ n < 232. -
- -

Validating a MemberExpression node - -

-x:Identifier[expr:Expression >> n:-?NumericLiteral] -
- -

succeeds with load type σ and store types { τ, … } -if: - -

    -
  • Lookup(Δ, Γ, x) = view where view is -an ArrayBufferView -type; -
  • the element size of view is bytes; -
  • the load type of view is σ; -
  • the store types of view are { τ, … }; -
  • ValidateExpression succeeds for expr with type intish; -
  • the source of n does not contain a . character; -
  • n = log2(bytes). -
- - - -

6.11 ValidateFloatCoercion(Δ, Γ, e)

- -

A call to the fround coercion is validated in the -context of a global environment Δ and a variable environment -Γ and validates as the type float. - -

Validating a CallExpression node - -

-f:Identifier(cexpr:CallExpression) -
- -

succeeds with type float if Lookup(Δ, -Γ, f) = fround and ValidateCall succeeds for -cexpr with actual return type float. - -

Alternatively, validating a CallExpression node - -

-f:Identifier(arg:Expression) -
- -

succeeds with type float if Lookup(Δ, -Γ, f) = fround -and ValidateExpression -succeeds for arg with type τ, where τ is a subtype -of floatish, double?, signed, -or unsigned. - - -

7 Linking

- -

An AOT implementation of asm.js must perform some internal dynamic -checks at link time to be able to safely generate AOT-compiled -exports. If any of the dynamic checks fails, the result of linking -cannot be an AOT-compiled module. The dynamically checked invariants -are: - -

    -
  • control must reach the module's return statement without throwing; -
  • all property access must resolve to data properties; -
  • the heap object (if provided) must be an instance of ArrayBuffer; -
  • the heap object's byteLength must be either 2n for n in [12, 24) or 224 · n for n ≥ 1; - -
  • all globals taken from the stdlib object must be -the SameValue -as the -corresponding standard -library of the same name. -
- -

If any of these conditions is not met, AOT compilation may produce -invalid results so the engine should fall back to an interpreted or -JIT-compiled implementation. - -

8 Operators

- -

8.1 Unary Operators

- - - - - - - - - - - - - - - - - - - - - - - - -
Unary OperatorType
+ - (signed) → double
- (unsigned) → double
- (double?) → double
- (float?) → double -
- - (int) → intish
- (double?) → double
- (float?) → floatish -
~(intish) → signed
!(int) → int
- -

Note that the special combined operator ~~ may be used -as a coercion from double or float? -to signed; see Unary -Expressions. - -

8.2 Binary Operators

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Binary OperatorType
+ - (double, double) → double
- (float?, float?) → floatish -
- - (double?, double?) → double
- (float?, float?) → floatish -
* - (double?, double?) → double
- (float?, float?) → floatish -
/ - (signed, signed) → intish
- (unsigned, unsigned) → intish
- (double?, double?) → double
- (float?, float?) → floatish -
% - (signed, signed) → intish
- (unsigned, unsigned) → intish
- (double?, double?) → double -
|, &, ^, <<, >>(intish, intish) → signed
>>>(intish, intish) → unsigned
<, <=, >, >=, ==, != - (signed, signed) → int
- (unsigned, unsigned) → int
- (double, double) → int
- (float, float) → int -
- -

9 Standard Library

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Standard LibraryType
- Infinity
- NaN -
double
- Math.acos
- Math.asin
- Math.atan
- Math.cos
- Math.sin
- Math.tan
- Math.exp
- Math.log -
(double?) → double
- Math.ceil
- Math.floor
- Math.sqrt -
- (double?) → double
- (float?) → float -
Math.abs - (signed) → signed
- (double?) → double
- (float?) → float -
- Math.min
- Math.max -
- (int, int) → signed
- (double, double) → double -
- Math.atan2
- Math.pow -
(double?, double?) → double
Math.imul(int, int) → signed
Math.froundfround
- Math.E
- Math.LN10
- Math.LN2
- Math.LOG2E
- Math.LOG10E
- Math.PI
- Math.SQRT1_2
- Math.SQRT2
-
double
- -

10 Heap View Types

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
View TypeElement Size (Bytes)Load TypeStore Types
Uint8Array1intishintish
Int8Array1intishintish
Uint16Array2intishintish
Int16Array2intishintish
Uint32Array4intishintish
Int32Array4intishintish
Float32Array4float?floatish, double?
Float64Array8double?float?, double?
- -

Acknowledgements

- -

Thanks to Martin Best, Brendan Eich, Andrew McCreight, and Vlad -Vukićević for feedback and encouragement.

- -

Thanks to Benjamin Bouvier, Douglas Crosher, and Dan Gohman for -contributions to the design and implementation, particularly for -float.

- -

Thanks to Jesse Ruderman and C. Scott Ananian for bug reports.

- -

Thanks to Michael Bebenita for diagrams.

- - - - \ No newline at end of file diff --git a/html/index.src.html b/html/index.src.html deleted file mode 100644 index 62772b9..0000000 --- a/html/index.src.html +++ /dev/null @@ -1,2228 +0,0 @@ - - - - - -asm.js - - - - - - - - - -
-

[TITLE]

- -

Working Draft — [DATE]

- -
-
Latest version: -
http://asmjs.org/spec/latest/ - -
Editors: -
- David Herman, - Mozilla, - -
- Luke Wagner, - Mozilla, - -
- Alon Zakai, - Mozilla, - -
-
- -

Abstract

- -

This specification defines asm.js, a strict subset -of JavaScript that can be used as a low-level, efficient target -language for compilers. This sublanguage effectively describes a sandboxed -virtual machine for memory-unsafe languages like C or C++. A -combination of static and dynamic validation allows JavaScript engines -to employ an ahead-of-time (AOT) optimizing compilation strategy for -valid asm.js code. - -

Status

- -

This specification is working towards a candidate draft for asm.js -version 1. Mozilla's SpiderMonkey JavaScript engine provides an -optimizing implementation of this draft. - -

Changelog

- -
    -
  • 18 August 2014 -
      -
    • better "putting it all together" example -
    -
  • 23 July 2014 -
      -
    • formatting cleanups -
    • added variadic function types to the Global Types section -
    -
  • 22 July 2014 -
      -
    • clarified formal structure with explicit validation rule names -
    • moved function table validation from annotations section to validation section -
    • separated case and default validation rules -
    • eliminated unused expected case type parameter -
    • corrected type checks to subtype checks in AdditiveExpression, BitwiseXORExpression, BitwiseANDExpression, BitwiseORExpression, and ConditionalExpression -
    -
  • 8 July 2014 -
      -
    • minor editorial bugfixes -
    • non-function foreign imports are mut -
    • tightened the language on linking restrictions -
    -
  • 7 July 2014 -
      -
    • added 32-bit floating point types -
    • renamed doublish to double? for symmetry with float? -
    • separated heap access checking into a separate validation section -
    • separated load and store types for heap views -
    • added Math.fround and singleton fround type -
    • added a Float Coercions section -
    • added uncoerced CallExpression nodes to Expression for float coercions -
    • added float coercions to initializers, return type annotations, and legal function calls -
    • added restriction preventing float coercions of FFI calls -
    • added float support for operators and Math functions -
    • added float to legal result types for ConditionalExpression -
    • added variadic Math.min and Math.max -
    • eliminated the allowance for 1-byte views to elide their index shift (to future-proof for large heaps) -
    • simplified and generalized link-time restrictions on heap size -
    -
  • 12 December 2013 -
      -
    • return type of Math.abs is signed -
    -
  • 11 October 2013 -
      -
    • unsigned is not an extern type -
    • added missing ! operator to UnaryExpression operators -
    • added note about ~~ to Unary Operators section -
    • added note about parenthesis agnosticism to Syntax section -
    • added note about ASI to Syntax section -
    • added -NumericLiteral cases everywhere -
    • function calls require explicit coercions -
    • eliminated type unknown, which is no longer needed -
    • return type of integer % is intish -
    -
- -

Table of Contents

- - - -

Introduction

- -

This specification defines asm.js, a strict subset of -JavaScript that can be used as a low-level, efficient target language -for compilers. The asm.js language provides an abstraction similar to -the C/C++ virtual machine: a large binary heap with efficient loads -and stores, integer and floating-point arithmetic, first-order -function definitions, and function pointers. - -

Programming Model

- -

The asm.js programming model is built around integer and -floating-point arithmetic and a virtual heap represented as -a typed -array. While JavaScript does not directly provide constructs for -dealing with integers, they can be emulated using two tricks: - -

    -
  • integer loads and stores can be performed using the typed arrays -API; and -
  • integer arithmetic is equivalent to the composition of -JavaScript's floating-point arithmetic operators with the integer -coercions performed by the bitwise operators. -
- -

As an example of the former, if we have -an Int32Array -view of the heap called HEAP32, then we can load the -32-bit integer at byte offset p: - - - -

-
HEAP32[p >> 2]|0
-
- -

The shift converts the byte offset to a 32-bit element offset, and -the bitwise coercion ensures that an out-of-bounds access is coerced -from undefined back to an integer. - - - -

As an example of integer arithmetic, addition can be performed by -taking two integer values, adding them with the built-in addition -operator, and coercing the result back to an integer via the bitwise -or operator: - -

-
(x+y)|0
-
- -

This programming model is directly inspired by the techniques -pioneered by the Emscripten -and Mandreel compilers. - -

Validation

- -

The asm.js sub-language is defined by a -static type system that can be checked -at JavaScript parse time. Validation of asm.js code is designed to be -"pay-as-you-go" in that it is never performed on code that does not -request it. An asm.js module requests validation by means -of a -special prologue -directive, similar to that of ECMAScript Edition -5's strict -mode: - -

-
function MyAsmModule() {
-    "use asm";
-    // module body
-}
-
- -

This explicit directive allows JavaScript engines to avoid -performing pointless and potentially costly validation on other -JavaScript code, and to report validation errors in developer consoles -only where relevant. - -

Ahead-Of-Time Compilation

- -

Because asm.js is a strict subset of JavaScript, this specification -only defines the validation logic—the execution semantics is -simply that of JavaScript. However, validated asm.js is amenable to -ahead-of-time (AOT) compilation. Moreover, the code generated by an -AOT compiler can be quite efficient, featuring: - -

    -
  • unboxed representations of integers and floating-point numbers; -
  • absence of runtime type checks; -
  • absence of garbage collection; and -
  • efficient heap loads and stores (with implementation strategies varying by platform). -
- -

Code that fails to validate must fall back to execution by -traditional means, e.g., interpretation and/or just-in-time (JIT) -compilation. - - - -

Linking

- -

Using an asm.js module requires calling its function to obtain an -object containing the module's exports; this is known -as linking. An asm.js module can also be given access to -standard libraries and custom JavaScript functions through linking. An -AOT implementation must perform certain dynamic -checks to check compile-time assumptions about the linked -libraries in order to make use of the compiled code. - -

This figure depicts a simple architecture of an AOT implementation -that otherwise employs a simple interpreter. If either dynamic or -static validation fails, the implementation must fall back to the -interpreter. But if both validations succeed, calling the module -exports executes the binary executable code generated by AOT -compilation. - -

- -
- -

External Code and Data

- -

Within an asm.js module, all code is fully statically typed and -limited to the very restrictive asm.js dialect. However, it is -possible to interact with recognized standard JavaScript libraries and -even custom dynamic JavaScript functions. - -

An asm.js module can take up to three optional parameters, -providing access to external JavaScript code and data: - -

    -
  • a standard library object, providing access to a -limited subset of the JavaScript standard -libraries; -
  • a foreign function interface (FFI), providing access to -custom external JavaScript functions; and -
  • a heap buffer, providing a -single ArrayBuffer -to act as the asm.js heap. -
- -

These objects allow asm.js to call into external JavaScript (and to -share its heap buffer with external JavaScript). Conversely, the -exports object returned from the module allows external JavaScript to -call into asm.js. - -

So in the general case, an asm.js module declaration looks like: - -

-
function MyAsmModule(stdlib, foreign, heap) {
-    "use asm";
-
-    // module body...
-
-    return {
-        export1: f1,
-        export2: f2,
-        // ...
-    };
-}
-
- -

Function parameters in asm.js are provided a type annotation by -means of an explicit coercion on function entry: - -

-
function geometricMean(start, end) {
-  start = start|0; // start has type int
-  end = end|0;     // end has type int
-  return +exp(+logSum(start, end) / +((end - start)|0));
-}
- -
- -

These annotations serve two purposes: first, to provide the -function's type signature so that the validator can enforce that all -calls to the function are well-typed; second, to ensure that even if -the function is exported and called by external JavaScript, its -arguments are dynamically coerced to the expected type. This ensures -that an AOT implementation can use unboxed value representations, -knowing that once the dynamic coercions have completed, the function -body never needs any runtime type checks. - -

Putting It All Together

- -

The following is a small but complete example of an asm.js module. - -

-
function GeometricMean(stdlib, foreign, buffer) {
-  "use asm";
-
-  var exp = stdlib.Math.exp;
-  var log = stdlib.Math.log;
-  var values = new stdlib.Float64Array(buffer);
-
-  function logSum(start, end) {
-    start = start|0;
-    end = end|0;
-
-    var sum = 0.0, p = 0, q = 0;
-
-    // asm.js forces byte addressing of the heap by requiring shifting by 3
-    for (p = start << 3, q = end << 3; (p|0) < (q|0); p = (p + 8)|0) {
-      sum = sum + +log(values[p>>3]);
-    }
-
-    return +sum;
-  }
-
-  function geometricMean(start, end) {
-    start = start|0;
-    end = end|0;
-
-    return +exp(+logSum(start, end) / +((end - start)|0));
-  }
-
-  return { geometricMean: geometricMean };
-}
-
- -

In a JavaScript engine that supports AOT compilation of asm.js, -calling the module on a proper global object and heap buffer would -link the exports object to use the statically compiled functions. - -

-
var heap = new ArrayBuffer(0x10000);          // 64k heap
-init(heap, START, END);                       // fill a region with input values
-var fast = GeometricMean(window, null, heap); // produce exports object linked to AOT-compiled code
-fast.geometricMean(START, END);               // computes geometric mean of input values
-
- -

By contrast, calling the module on a standard library object -containing something other than the true Math.exp or -Math.log would fail to produce AOT-compiled code: - -

-
var bogusGlobal = {
-  Math: {
-    exp: function(x) { return x; },
-    log: function(x) { return x; }
-  },
-  Float64Array: Float64Array
-};
-
-var slow = GeometricMean(bogusGlobal, null, heap); // produces purely-interpreted/JITted version
-console.log(slow.geometricMean(START, END));       // computes bizarro-geometric mean thanks to bogusGlobal
-
- - - -

Types

- -

Validation of an asm.js module relies on a static type system that -classifies and constrains the syntax. This section defines the types -used by the validation logic. - -

Value Types

- -

Validation in asm.js limits JavaScript programs to only use operations -that can be mapped closely to efficient data representations and -machine operations of modern architectures, such as 32-bit integers -and integer arithmetic. - -

The types of asm.js values are inter-related by a subtyping -relation, which can be represented pictorially: - -

- -
- -

The light boxes represent arbitrary JavaScript values that may flow -freely between asm.js code and external JavaScript code. - -

The dark boxes represent types that are disallowed from escaping -into external (i.e., non-asm.js) JavaScript code. (These values can be -given efficient, unboxed representations in optimized asm.js -implementations that would be unsound if they were allowed to escape.) - -

The meta-variables σ and τ are used to stand for value -types. - -

void

- -

The void type is the type of functions that -are not supposed to return any useful value. As JavaScript functions, -they produce the undefined value, but asm.js code is not -allowed to make use of this value; functions with return -type void can only be called for effect. - -

double

- -

The double type is the type of ordinary -JavaScript double-precision floating-point numbers. - -

signed

- -

The signed type is the type of signed -32-bit integers. While there is no direct concept of integers in -JavaScript, 32-bit integers can be represented as doubles, and integer -operations can be performed with JavaScript arithmetic, relational, -and bitwise operators. - -

unsigned

- -

The unsigned type is the type of unsigned -32-bit integers. Again, these are not a first-class concept in -JavaScript, but can be represented as floating-point numbers. - -

int

- -

The int type is the type of 32-bit integers -where the signedness is not known. In asm.js, the type of a variable -never has a known signedness. This allows them to be compiled as -32-bit integer registers and memory words. However, this -representation creates an overlap between signed and unsigned numbers -that causes an ambiguity in determining which JavaScript number they -represent. For example, the bit pattern 0xffffffff could -represent 4294967295 or -1, depending on the signedness. For this -reason, values of the int type are disallowed from -escaping into external (non-asm.js) JavaScript code. - -

fixnum

- -

The fixnum type is the type of integers in the -range [0, 231)—that is, the range of integers such -that an unboxed 32-bit representation has the same value whether it is -interpreted as signed or unsigned. - - -

intish

- -

Even though JavaScript only supports floating-point arithmetic, -most operations can simulate integer arithmetic by coercing their -result to an integer. For example, adding two integers may overflow -beyond the 32-bit range, but coercing the result back to an integer -produces the same 32-bit integer as integer addition in, say, C. - -

The intish type represents the result of a -JavaScript integer operation that must be coerced back to an integer -with an explicit coercion -(ToInt32 -for signed integers -and ToUint32 -for unsigned integers). Validation requires all intish -values to be immediately passed to an operator or standard library -that performs the appropriate coercion or else dropped via an -expression statement. This way, each integer operation can be -compiled directly to machine operations. - -

The one operator that does not support this approach is -multiplication. (Multiplying two large integers can result in a large -enough double that some lower bits of precision are lost.) So asm.js -does not support applying the multiplication operator to integer -operands. Instead, the -proposed Math.imul -function is recommended as the proper means of implementing integer -multiplication. - - -

double?

- -

The double? type represents operations that -are expected to produce a double but may also produce -undefined, and so must be coerced back to a number -via ToNumber. -Specifically, reading out of bounds from a typed array -produces undefined. - -

float

- -

The float type is the type of 32-bit -floating-point numbers. - -

float?

- -

The float? type represents operations that -are expected to produce a float but, similar -to double?, may also produce undefined and -so must be coerced back to a 32-bit floating point number -via fround. -Specifically, reading out of bounds from a typed array -produces undefined. - -

floatish

- -

Similar to integers, JavaScript can almost support 32-bit -floating-point arithmetic, but requires extra coercions to properly -emulate the 32-bit semantics. As proved in -When is double -rounding innocuous? (Figueroa 1995), both the 32- and 64-bit -versions of standard arithmetic operations produce equivalent results -when given 32-bit inputs and coerced to 32-bit outputs. - -

The floatish type, -like intish, represents the result of a JavaScript 32-bit -floating-point operations that must be coerced back to a 32-bit -floating-point value with an -explicit fround -coercion. Validation requires all floatish values to be -immediately passed to an operator or standard library that performs -the appropriate coercion or else dropped via an expression -statement. This way, each 32-bit floating-point operation can be -compiled -directly to machine operations. - -

extern

- -The abstract extern type represents the root -of all types that can escape back into external JavaScript—in -other words, the light boxes in the above diagram. - -

Global Types

- -

Variables and functions defined at the top-level scope of an asm.js -module can have additional types beyond -the value types. These include: - -

    -
  • value types τ; -
  • ArrayBufferView types IntnArray, UintnArray, and FloatnArray; -
  • function types ((σ, …) → τ) ∧ … ∧ ((σ′, …) → τ′); -
  • variadic function types ((σ, σ) → τ) ∧ … ∧ ((σ′, σ′) → τ′); -
  • function table types ((σ, …) → τ)[n]; -
  • the special type fround of Math.fround; and -
  • the FFI function type Function. -
- -

The "∧" notation for function types serves to represent -overloaded functions and operators. For example, -the Math.abs function is -overloaded to accept either integers or floating-point numbers, and -returns a different type in each case. Similarly, many of -the operators have overloaded types. - -

The meta-variable γ is used to stand for global types. - -

Environments

- -

Validating an asm.js module depends on tracking contextual -information about the set of definitions and variables in scope. This -section defines the environments used by the validation -logic. - -

Global Environment

- -

An asm.js module is validated in the context of a global -environment. The global environment maps each global variable to -its type as well as indicating whether the variable is mutable: - -

{ x : (mut|imm) γ, … }
- -

The meta-variable Δ is used to stand for a global environment. - -

Variable Environment

- -

In addition to the global environment, each function -body in an asm.js module is validated in the context of -a variable environment. The variable environment maps each -function parameter and local variable to its value type: - -

{ x : τ, … } - -

The meta-variable Γ is used to stand for a variable environment. - -

Environment Lookup

- -

Looking up a variable's type - -

-Lookup(Δ, Γ, x) -
- -

is defined by: - -

    -
  • τ if x : τ occurs in Γ; -
  • γ if x does not occur in Γ and x -: mut γ or x : imm γ -occurs in Δ -
- -

If x does not occur in either environment then -the Lookup function has no result. - -

Syntax

- -

Validation of an asm.js module is specified by reference to -the ECMAScript -grammar, but conceptually operates at the level of abstract -syntax. In particular, an asm.js validator must obey the following -rules: - -

    -
  • Empty statements (;) are always ignored, whether in -the top level of a module or inside an asm.js function body. -
  • No variables bound anywhere in an asm.js module (whether in the -module function parameter list, global variable declarations, asm.js -function names, asm.js function parameters, or local variable -declarations) may have the name eval -or arguments. -
  • Where it would otherwise parse equivalently in JavaScript, -parentheses are meaningless. Even where the specification matches on -specific productions of Expression such as literals, the -source may contain extra meaningless parentheses without affecting -validation. -
  • Automatic semicolon insertion is respected. An asm.js source file -may omit semicolons wherever JavaScript allows them to be omitted. -
- -

These rules are otherwise left implicit in the rest of the -specification. - -

Annotations

- -

All variables in asm.js are explicitly annotated with type -information so that their type can be statically enforced by -validation. - -

Parameter Type Annotations

- -

Every parameter in an asm.js function is provided with an explicit -type annotation in the form of a coercion. This coercion serves two -purposes: the first is to make the parameter type statically apparent -for validation; the second is to ensure that if the function is -exported, the arguments dynamically provided by external JavaScript -callers are coerced to the expected type. For example, a bitwise OR -coercion annotates a parameter as having type int: - -

-
function add1(x) {
-    x = x|0; // x : int
-    return (x+1)|0;
-}
-
- -

In an AOT implementation, the body of the function can be -implemented fully optimized, and the function can be given two entry -points: an internal entry point for asm.js callers, which are -statically known to provide the proper type, and an external dynamic -entry point for JavaScript callers, which must perform the full -coercions (which might involve arbitrary JavaScript computation, e.g., -via implicit calls to valueOf). - -

There are three recognized parameter type annotations: - -

-x:Identifier = x:Identifier|0;
-x:Identifier = +x:Identifier;
-x:Identifier = f:Identifier(x:Identifier); -
- -

The first form annotates a parameter as type int, the -second as type double, and the third as -type float. In the latter case, -Lookup(Δ, Γ, f) must -be fround. - -

Return Type Annotations

- -

An asm.js function's formal return type is determined by -the last statement in the function body, which for -non-void functions is required to be -a ReturnStatement. This distinguished return statement may -take one of five forms: - -

-return +e:Expression;
-return e:Expression|0;
-return n:-?NumericLiteral;
-return f:Identifier(arg:Expression);
-return; -
- -

The first form has return type double. The second has -type signed. The third has return -type double if n is composed of a floating-point -literal, i.e., a numeric literal with the character . in -its source; alternatively, if n is composed of an integer -literal and has its value in the range [-231, -231), the return statement has return -type signed. The fourth form has return -type float, and the fifth has return -type void. - -

If the last statement in the function body is not -a ReturnStatement, or if the function body has no non-empty -statements (other than the initial declarations and -coercions—see Function -Declarations), the function's return type is void. - -

Function Type Annotations

- -

The type of a function declaration - -

-function f:Identifier(x:Identifier) {
-    (x:Identifier = AssignmentExpression;)
-    (var (y:Identifier = (-?NumericLiteral | Identifier(-?NumericLiteral))),)
-    body:Statement
-} -
- -

is (σ,…) → τ where σ,… are the -types of the parameters, as provided by -the parameter type -annotations, and τ is the formal return type, as provided by -the return type annotation. The -variable f is stored in -the global environment with -type imm (σ,…) → τ. - -

Variable Type Annotations

- -

The types of variable declarations are determined by their -initializer, which may take one of two forms: - -

-n:-?NumericLiteral
-f:Identifier(n:-?NumericLiteral) - -
- -

In the first case, the variable type is double -if n's source contains the character .; -otherwise n may be an integer literal in the range -[-231, 232), in which case the variable type -is int. - -

In the second case, the variable type -is float. Lookup(Δ, Γ, f) -must be fround and n must be a floating-point -literal with the character . in its source. - - - -

Global Variable Type Annotations

- -

A global variable declaration is a VariableStatement node -in one of several allowed forms. Validating global variable -annotations takes a Δ as input and produces as output a new -Δ′ by adding the variable binding to Δ. - -

A global program variable is initialized to a literal: - -

-var x:Identifier = n:-?NumericLiteral;
-var x:Identifier = f:Identifier(n:-?NumericLiteral); -
- -

The global variable x is stored in -the global environment with -type mut τ, where τ is determined in the same way -as local variable type -annotations. - -

A standard library import is of one of the following two forms: - -

-var x:Identifier = stdlib:Identifier.y:Identifier;
-var x:Identifier = stdlib:Identifier.Math.y:Identifier; -
- -

The variable stdlib must match the first parameter of -the module declaration. The global -variable x is stored in -the global environment with -type imm γ, where γ is the type of -library y or Math.y as specified by -the standard library types. - -

A foreign import is of one of the following three forms: - -

-var x:Identifier = foreign:Identifier.y:Identifier;
-var x:Identifier = foreign:Identifier.y:Identifier|0;
-var x:Identifier = +foreign:Identifier.y:Identifier; -
- -

The variable foreign must match the second parameter of -the module declaration. The global -variable x is stored in -the global environment with -type imm Function for the first form, mut -int for the second, and mut double for the third. - -

A global heap view is of the following form: - -

-var x:Identifier = new stdlib:Identifier.view:Identifier(heap:Identifier); -
- -

The variable stdlib must match the first parameter of -the module declaration and the -variable heap must match the third. The -identifier view must be one of the -standard ArrayBufferView -type names. The global variable x is stored in -the global environment with -type imm -view. - -

Function Table Types

- -

A function table is a VariableStatement of the form: - -

-var x:Identifier = [f0:Identifier, f:Identifier,]; -
- -

The function table x is stored in -the global environment with -type imm ((σ,…) → τ)[n] -where (σ,…) → τ is the type of f in the -global environment and n is the length of the array literal. - - - -

Validation Rules

- -

To ensure that a JavaScript function is a proper asm.js module, it -must first be statically validated. This section specifies the -validation rules. The rules operate on JavaScript abstract syntax, -i.e., the output of a JavaScript parser. The non-terminals refer to -parse nodes defined by productions in -the ECMAScript -grammar, but note that the asm.js validator only accepts a subset -of legal JavaScript programs. - -

The result of a validation operation is either -a success, indicating that a parse node is statically valid -asm.js, or a failure, indicating that the parse node is -statically invalid asm.js. - -

ValidateModule(f)

- -

The ValidateModule rule validates an asm.js module, which -is either a FunctionDeclaration -or FunctionExpression node. - -

Validating a module of the form - -

-function f:Identifieropt((stdlib:Identifier(, foreign:Identifier(, heap:Identifier)opt)opt)opt) {
-    "use asm";

-    var:VariableStatement
-    fun:FunctionDeclaration
- -    table:VariableStatement
-    exports:ReturnStatement
-} -
- -

succeeds if: - -

    -
  • f, stdlib, foreign, heap, and -the var, fun, and table variables are all -mutually distinct; -
  • the global environment Δ is constructed in three stages: -
      -
    1. the global declarations are - validated in an empty initial environment Δ0, - producing a new global environment Δ1; -
    2. the types from the function - type annotations in the fun declarations are extracted - using Δ1, and then added to Δ1 to - produce Δ2; - -
    3. the types of the function - tables in the table declarations are extracted - using Δ2, and their types are added to - Δ2 to produce the completed global type environment - Δ. -
    -
  • for each fun declaration, ValidateFunction succeeds with environment Δ; -
  • for each table declaration, ValidateFunctionTable succeeds with environment Δ; and -
  • ValidateExport succeeds for exports with environment Δ. -
- - -

ValidateExport(Δ, s)

- -

The ValidateExport rule validates an asm.js module's -export declaration. An export declaration is -a ReturnStatement returning either a single asm.js function -or an object literal exporting multiple asm.js functions. - -

Validating an export declaration node - -

-return { (x:Identifier : f:Identifier), }; -
- -

succeeds if for each f, Δ(f) = imm -γ where γ is a function type (σ,…) → -τ. - -

Validating an export declaration node - -

-return f:Identifier; -
- -

succeeds if Δ(f) = imm γ where -γ is a function type (σ,…) → τ. - -

ValidateFunctionTable(Δ, s)

- -

The ValidateFunctionTable rule validates an asm.js -module's function table declaration. A function table declaration is -a VariableStatement binding an identifier to an array -literal. - -

Validating a function table of the form - -

-var x:Identifier = [f:Identifier,]; -
- -

succeeds if: - -

    -
  • the length n of the array literal is 2m for some m ≥ 0; -
  • Δ(x) = imm ((σ,…) → τ)[n]; and -
  • for each f, Δ(f) = (σ,…) → τ. -
- - -

ValidateFunction(Δ, f)

- -

The ValidateFunction rule validates an asm.js function -declaration, which is a FunctionDeclaration node. - -

Validating a function declaration of the form - -

-function f:Identifier(x:Identifier,) {
-    (x:Identifier = AssignmentExpression;)
-    (var (y:Identifier = (-?NumericLiteral | Identifier(-?NumericLiteral))),)
-    body:Statement
-} -
- -

succeeds if: - -

    -
  • Δ(f) = imm (σ,…) → τ; -
  • the x and y variables are all mutually distinct; -
  • the variable environment Γ is constructed by mapping each -parameter x to its -corresponding parameter type -annotation (annotations must appear in the same order as the -parameters) and each local variable y to -its variable type annotation; -
  • for each body -statement, ValidateStatement -succeeds with environments Δ and Γ and expected return -type τ. -
- -

ValidateStatement(Δ, Γ, τ, s)

- -

The ValidateStatement rule validates an asm.js statement. -Each statement is validated in the context of a global -environment Δ, a variable environment -Γ, and an expected return type τ. Unless otherwise -explicitly stated, a recursive validation of a subterm uses the same -context as its containing term. - -

Block

- -

Validating a Block statement node - -

-{ stmt:Statement} -
- -

succeeds -if ValidateStatement -succeeds for each stmt. - -

ExpressionStatement

- -

Validating an ExpressionStatement node - -

-cexpr:CallExpression ; -
- -

succeeds if ValidateCall -succeeds for cexpr with actual return type void. - -

Validating an ExpressionStatement node - -

-expr:Expression ; -
- -

succeeds -if ValidateExpression -succeeds for expr with some type σ. - -

EmptyStatement

- -

Validating an EmptyStatement node always succeeds. - -

IfStatement

- -

Validating an IfStatement node - -

-if ( expr:Expression ) stmt1:Statement else stmt2:Statement -
- -

succeeds -if ValidateExpression -succeeds for expr with a subtype of int -and ValidateStatement -succeeds for stmt1 and stmt2. - -

Validating an IfStatement node - -

-if ( expr:Expression ) stmt:Statement -
- -

succeeds -if ValidateExpression -succeeds for expr with a subtype of int -and ValidateStatement -succeeds for stmt. - -

ReturnStatement

- -

Validating a ReturnStatement node - -

-return expr:Expression ; -
- -

succeeds -if ValidateExpression -succeeds for expr with a subtype of the expected return type -τ. - -

Validating a ReturnStatement node - -

-return ; -
- -

succeeds if the expected return type τ is void. - - -

IterationStatement

- -

Validating an IterationStatement node - -

-while ( expr:Expression ) stmt:Statement -
- -

succeeds -if ValidateExpression -succeeds for expr with a subtype of int -and ValidateStatement -succeeds for stmt. - -

Validating an IterationStatement node - -

-do stmt:Statement while ( expr:Expression ) ; -
- -

succeeds -if ValidateStatement -succeeds for stmt -and ValidateExpression -succeeds for expr with a subtype of int. - -

Validate an IterationStatement node - -

-for ( init:ExpressionNoInopt ; test:Expressionopt ; update:Expressionopt ) body:Statement -
- -

succeeds if: - -

- -

BreakStatement

- -

Validating a BreakStatement node - -

-break Identifieropt ; -
- -

always succeeds. - -

ContinueStatement

- -

Validating a ContinueStatement node - -

-continue Identifieropt ; -
- -

always succeeds. - -

LabelledStatement

- -

Validating a LabelledStatement node - -

-Identifier : body:Statement -
- -

succeeds -if ValidateStatement -succeeds for body. - -

SwitchStatement

- -

Validating a SwitchStatement node - -

-switch ( test:Expression ) { case:CaseClausedefault:DefaultClauseopt } -
- -

succeeds if - -

    -
  • ValidateExpression succeeds for test with a subtype of signed; -
  • ValidateCase succeeds for each case; -
  • each case value is distinct; -
  • the difference between the maximum and minimum case values is less than 231; and -
  • ValidateDefault succeeds for default. -
- - - - - - -

ValidateCase(Δ, Γ, τ, c)

- -

Cases in a switch block are validated in the context -of a global environment Δ, a variable -environment Γ, and an expected return type τ. Unless -otherwise explicitly stated, a recursive validation of a subterm uses -the same context as its containing term. - - - - - - - -

Validating a CaseClause node - -

-case n:-?NumericLiteral : stmt:Statement… -
- -

succeeds if - -

    -
  • the source of n does not contain a . character; -
  • n is in the range [-231, 231); and -
  • ValidateStatement succeeds for each stmt. -
- -

ValidateDefault(Δ, Γ, τ, d)

- -

The default case in a switch block is validated in the -context of a global environment Δ, a variable -environment Γ, and an expected return type τ. Unless -otherwise explicitly stated, a recursive validation of a subterm uses -the same context as its containing term. - - - -

Validating a DefaultClause node - -

-default : stmt:Statement… -
- -

succeeds -if ValidateStatement -succeeds for each stmt. - - -

ValidateExpression(Δ, Γ, e)

- -

Each expression is validated in the context of a global -environment Δ and a variable environment -Γ, and validation produces the type of the expression as a -result. Unless otherwise explicitly stated, a recursive validation of -a subterm uses the same context as its containing term. - -

Expression

- -

Validating an Expression node - -

-expr1:AssignmentExpression ,, exprn:AssignmentExpression -
- -

succeeds with type τ if for every i -< n, one of the following conditions holds: - -

- -

and ValidateExpression -succeeds for exprn with type τ. - -

NumericLiteral

- -

Validating a NumericLiteral node - -

    -
  • succeeds with type double if the source contains a . character; or -validates as type double; -
  • succeeds with type fixnum if the source does not contain a . character and its numeric value is in the range [0, 231); or -
  • succeeds with type unsigned if the source does not contain a . character and its numeric value is in the range [231, 232). -
- -

Note that the case of negative integer constants is handled -under UnaryExpression. - -

Note that integer literals outside the range [0, 232) -are invalid, i.e., fail to validate. - -

Identifier

- -

Validating an Identifier node - -

-x:Identifier -
- -

succeeds with type τ if Lookup(Δ, Γ, x) = τ. - -

CallExpression

- -

Validating a CallExpression node succeeds with -type float -if ValidateFloatCoercion -succeeds. - -

MemberExpression

- -

Validating a MemberExpression node succeeds with type -τ -if ValidateHeapAccess -succeeds with load type τ. - -

AssignmentExpression

- -

Validating an AssignmentExpression node - -

-x:Identifier = expr:AssignmentExpression -
- -

succeeds with type τ -if ValidateExpression -succeeds for the nested AssignmentExpression with type τ -and one of the following two conditions holds: - -

    -
  • x is bound in Γ as a supertype of τ; or -
  • x is not bound in Γ and is bound to a mutable supertype of τ in Δ. -
- -

Validating an AssignmentExpression node - -

-lhs:MemberExpression = rhs:AssignmentExpression -
- -

succeeds with type τ -if ValidateExpression -succeeds for rhs with type τ -and ValidateHeapAccess -succeeds for lhs with τ as one of its legal store types. - - - -

UnaryExpression

- -

Validating a UnaryExpression node of the form - -

--NumericLiteral -
- -

succeeds with type signed if -the NumericLiteral source does not contain a . -character and the numeric value of the expression is in the range -[-231, 0). - -

Validating a UnaryExpression node of the form - -

-+cexpr:CallExpression -
- -

succeeds with type double -if ValidateCall succeeds -for cexpr with actual return type double. - -

Validating a UnaryExpression node of the form - -

-op:(+|-|~|!)arg:UnaryExpression -
- -

succeeds with type τ if the type of op is … -∧ (σ) → τ ∧ … -and ValidateExpression -succeeds with a subtype of σ. - -

Validating a UnaryExpression node of the form - -

-~~arg:UnaryExpression -
- -

succeeds with type signed -if ValidateExpression -succeeds for arg with a subtype of either double -or float?. - -

MultiplicativeExpression

- -

Validating a MultiplicativeExpression node - -

-lhs:MultiplicativeExpression op:(*|/|%) rhs:UnaryExpression -
- -

succeeds with type τ if: - -

- -

Validating a MultiplicativeExpression node - -

-expr:MultiplicativeExpression * n:-?NumericLiteral
-n:-?NumericLiteral * expr:UnaryExpression -
- -

succeeds with type intish if the source of n -does not contain a . character and -220 -< n < 220 -and ValidateExpressionexpr with a subtype of int. - -

AdditiveExpression

- -

Validating an AdditiveExpression node - -

-expr1 (+|-)(+|-) exprn -
- -

succeeds with type intish if: - -

- -

Otherwise, validating an AdditiveExpression node - -

-lhs:AdditiveExpression op:(+|-) rhs:MultiplicativeExpression -
- -

succeeds with type double if: - -

- -

ShiftExpression

- -

Validating a ShiftExpression node - -

-lhs:ShiftExpression op:(<<|>>|>>>) rhs:AdditiveExpression - -
- -

succeeds with type τ if - -

- -

RelationalExpression

- -

Validating a RelationalExpression node - -

-lhs:RelationalExpression op:(<|>|<=|>=) rhs:ShiftExpression - -
- -

succeeds with type τ if - -

- -

EqualityExpression

- -

Validating an EqualityExpression node - -

-lhs:EqualityExpression op:(==|!=) rhs:RelationalExpression - -
- -

succeeds with type τ if - -

- -

BitwiseANDExpression

- -

Validating a BitwiseANDExpression node - -

-lhs:BitwiseANDExpression & rhs:EqualityExpression
-
- -

succeeds with type signed -if ValidateExpression -succeeds for lhs and rhs with -a subtype of intish. - -

BitwiseXORExpression

- -

Validating a BitwiseXORExpression node - -

-lhs:BitwiseXORExpression ^ rhs:BitwiseANDExpression
-
- -

succeeds with type signed -if ValidateExpression -succeeds for lhs and rhs with -a subtype of intish. - -

BitwiseORExpression

- -

Validating a BitwiseORExpression node - -

-cexpr:CallExpression |0
-
- -

succeeds with type signed -if ValidateCall succeeds -for cexpr with actual return type signed. - -

Validating a BitwiseORExpression node - -

-lhs:BitwiseORExpression | rhs:BitwiseXORExpression
-
- -

succeeds with type signed -if ValidateExpression -succeeds for lhs and rhs with -a subtype of intish. - -

ConditionalExpression

- -

Validating a ConditionalExpression node - -

-test:BitwiseORExpression ? cons:AssignmentExpression : alt:AssignmentExpression -
- -

succeeds with type τ if: - -

- -

Parenthesized Expression

- -

Validating a parenthesized expression node - -

-( expr:Expression ) -
- -

succeeds with type τ -if ValidateExpression -succeeds for expr with type τ. - - -

ValidateCall(Δ, Γ, τ, e)

- -

Each function call expression is validated in the context of a -global environment Δ and a variable environment Γ, and -validates against an actual return type τ, which was -provided from the context in which the function call appears. A -recursive validation of a subterm uses the same context as its -containing term. - -

Validating a CallExpression node - -

-f:Identifier(arg:Expression,) -
- -

with actual return type τ succeeds if one of the following -conditions holds: - -

    -
  • ValidateFloatCoercion -succeeds for the node; -
  • Lookup(Δ, Γ, f) = … ∧ -(σ,…) → τ ∧ … -and ValidateExpression -succeeds for each arg with a subtype of its corresponding -σ; or -
  • Lookup(Δ, Γ, f) = … ∧ -(σ1,…,σn) -→ τ ∧ … -and ValidateExpression -succeeds for the first n argi expressions -with subtypes of their corresponding σi and -the remaining arg expressions with subtypes of σ. -
- -

Alternatively, validating the CallExpression succeeds with -any actual return type τ other than float -if Lookup(Δ, Γ, f) -= Function -and ValidateExpression -succeeds for each arg with a subtype of extern. - - - -

Validating a CallExpression node - -

-x:Identifier[index:Expression & n:-?NumericLiteral](arg:Expression,) -
- -

succeeds with actual return type τ if: - -

    -
  • the source of n does not contain a . character; -
  • Lookup(Δ, -Γ, x) = ((σ,…) → -τ)[n+1]; -
  • ValidateExpression -succeeds for index with a subtype of intish; and -
  • ValidateExpression -succeeds for each arg with a subtype of its corresponding -σ. -
- - - -

ValidateHeapAccess(Δ, Γ, e)

- -

Each heap access expression is validated in the context of a global -environment Δ and a variable environment Γ, and validation -produces a load type as well as a set of legal store -types as a result. These types are determined by -the heap view types corresponding to -each ArrayBufferView -type. - -

Validating a MemberExpression node - -

-x:Identifier[n:-?NumericLiteral] -
- -

succeeds with load type σ and store types { τ, … } if: - -

    -
  • Lookup(Δ, Γ, x) = view -where view is -an ArrayBufferView -type; -
  • the load type of view is σ; -
  • the store types of view are { τ, … }; -
  • the source of n does not contain a . character; -
  • 0 ≤ n < 232. -
- -

Validating a MemberExpression node - -

-x:Identifier[expr:Expression >> n:-?NumericLiteral] -
- -

succeeds with load type σ and store types { τ, … } -if: - -

    -
  • Lookup(Δ, Γ, x) = view where view is -an ArrayBufferView -type; -
  • the element size of view is bytes; -
  • the load type of view is σ; -
  • the store types of view are { τ, … }; -
  • ValidateExpression succeeds for expr with type intish; -
  • the source of n does not contain a . character; -
  • n = log2(bytes). -
- - - -

ValidateFloatCoercion(Δ, Γ, e)

- -

A call to the fround coercion is validated in the -context of a global environment Δ and a variable environment -Γ and validates as the type float. - -

Validating a CallExpression node - -

-f:Identifier(cexpr:CallExpression) -
- -

succeeds with type float if Lookup(Δ, -Γ, f) = fround and ValidateCall succeeds for -cexpr with actual return type float. - -

Alternatively, validating a CallExpression node - -

-f:Identifier(arg:Expression) -
- -

succeeds with type float if Lookup(Δ, -Γ, f) = fround -and ValidateExpression -succeeds for arg with type τ, where τ is a subtype -of floatish, double?, signed, -or unsigned. - - -

Linking

- -

An AOT implementation of asm.js must perform some internal dynamic -checks at link time to be able to safely generate AOT-compiled -exports. If any of the dynamic checks fails, the result of linking -cannot be an AOT-compiled module. The dynamically checked invariants -are: - -

    -
  • control must reach the module's return statement without throwing; -
  • all property access must resolve to data properties; -
  • the heap object (if provided) must be an instance of ArrayBuffer; -
  • the heap object's byteLength must be either 2n for n in [12, 24) or 224 · n for n ≥ 1; - -
  • all globals taken from the stdlib object must be -the SameValue -as the -corresponding standard -library of the same name. -
- -

If any of these conditions is not met, AOT compilation may produce -invalid results so the engine should fall back to an interpreted or -JIT-compiled implementation. - -

Operators

- -

Unary Operators

- - - - - - - - - - - - - - - - - - - - - - - - -
Unary OperatorType
+ - (signed) → double
- (unsigned) → double
- (double?) → double
- (float?) → double -
- - (int) → intish
- (double?) → double
- (float?) → floatish -
~(intish) → signed
!(int) → int
- -

Note that the special combined operator ~~ may be used -as a coercion from double or float? -to signed; see Unary -Expressions. - -

Binary Operators

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Binary OperatorType
+ - (double, double) → double
- (float?, float?) → floatish -
- - (double?, double?) → double
- (float?, float?) → floatish -
* - (double?, double?) → double
- (float?, float?) → floatish -
/ - (signed, signed) → intish
- (unsigned, unsigned) → intish
- (double?, double?) → double
- (float?, float?) → floatish -
% - (signed, signed) → intish
- (unsigned, unsigned) → intish
- (double?, double?) → double -
|, &, ^, <<, >>(intish, intish) → signed
>>>(intish, intish) → unsigned
<, <=, >, >=, ==, != - (signed, signed) → int
- (unsigned, unsigned) → int
- (double, double) → int
- (float, float) → int -
- -

Standard Library

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Standard LibraryType
- Infinity
- NaN -
double
- Math.acos
- Math.asin
- Math.atan
- Math.cos
- Math.sin
- Math.tan
- Math.exp
- Math.log -
(double?) → double
- Math.ceil
- Math.floor
- Math.sqrt -
- (double?) → double
- (float?) → float -
Math.abs - (signed) → signed
- (double?) → double
- (float?) → float -
- Math.min
- Math.max -
- (int, int) → signed
- (double, double) → double -
- Math.atan2
- Math.pow -
(double?, double?) → double
Math.imul(int, int) → signed
Math.froundfround
- Math.E
- Math.LN10
- Math.LN2
- Math.LOG2E
- Math.LOG10E
- Math.PI
- Math.SQRT1_2
- Math.SQRT2
-
double
- -

Heap View Types

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
View TypeElement Size (Bytes)Load TypeStore Types
Uint8Array1intishintish
Int8Array1intishintish
Uint16Array2intishintish
Int16Array2intishintish
Uint32Array4intishintish
Int32Array4intishintish
Float32Array4float?floatish, double?
Float64Array8double?float?, double?
- -

Acknowledgements

- -

Thanks to Martin Best, Brendan Eich, Andrew McCreight, and Vlad -Vukićević for feedback and encouragement.

- -

Thanks to Benjamin Bouvier, Douglas Crosher, and Dan Gohman for -contributions to the design and implementation, particularly for -float.

- -

Thanks to Jesse Ruderman and C. Scott Ananian for bug reports.

- -

Thanks to Michael Bebenita for diagrams.

- - - diff --git a/html/subtypes.graffle b/html/subtypes.graffle deleted file mode 100644 index e2b452d..0000000 --- a/html/subtypes.graffle +++ /dev/null @@ -1,1505 +0,0 @@ - - - - - ActiveLayerIndex - 0 - ApplicationVersion - - com.omnigroup.OmniGraffle - 139.18.0.187838 - - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {1152, 733}} - Class - SolidGraphic - ID - 2 - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - BaseZoom - 0 - CanvasOrigin - {0, 0} - ColumnAlign - 1 - ColumnSpacing - 36 - CreationDate - 2013-06-07 22:05:55 +0000 - Creator - Michael Bebenita - DisplayScale - 1 0/72 in = 1.0000 in - GraphDocumentVersion - 8 - GraphicsList - - - Class - LineGraphic - ID - 32 - Points - - {140.2999963760376, 271.59995756244513} - {140.2999963760376, 223.19999408721924} - - Style - - stroke - - Color - - b - 0.398864 - g - 0.398857 - r - 0.398869 - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 3 - - - - - Bounds - {{79.199997901916504, 180.00000508721922}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - ID - 30 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - FillType - 2 - GradientAngle - 90 - GradientColor - - b - 0.6 - g - 0.6 - r - 0.6 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf0 floatish} - - - - Class - LineGraphic - Head - - ID - 27 - - ID - 29 - Points - - {140.21845543143303, 366.19997937971277} - {139.82966014768195, 317.79966534952058} - - Style - - stroke - - Color - - b - 0.398864 - g - 0.398857 - r - 0.398869 - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 3 - - - Tail - - ID - 28 - - - - Bounds - {{79.19999885559082, 367.19994713897705}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - FontInfo - - Color - - b - 0.298039 - g - 0.298039 - r - 0.298039 - - - ID - 28 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - FillType - 2 - GradientAngle - 90 - GradientColor - - b - 0.6 - g - 0.6 - r - 0.6 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;\red0\green0\blue0;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf2 float} - - - - Bounds - {{79.19999885559082, 273.59999465942383}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - ID - 27 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - FillType - 2 - GradientAngle - 90 - GradientColor - - b - 0.6 - g - 0.6 - r - 0.6 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf0 float\cf0 ?} - - - - Class - LineGraphic - Head - - ID - 8 - - ID - 26 - Points - - {578.18522311685604, 273.09125784684301} - {494.61476306844685, 223.70871543111116} - - Style - - stroke - - Color - - b - 0.398864 - g - 0.398857 - r - 0.398869 - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 3 - - - Tail - - ID - 11 - - - - Class - LineGraphic - Head - - ID - 10 - - ID - 25 - Points - - {517.47714205273303, 460.0366604156489} - {476.12283413256966, 411.16332286230505} - - Style - - stroke - - Color - - b - 0.398864 - g - 0.398857 - r - 0.398869 - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 3 - - - Tail - - ID - 15 - - - - Class - LineGraphic - Head - - ID - 12 - - ID - 24 - Points - - {555.32281413256976, 460.0366604156489} - {596.67712205273301, 411.16332286230511} - - Style - - stroke - - Color - - b - 0.398864 - g - 0.398857 - r - 0.398869 - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 3 - - - Tail - - ID - 15 - - - - Class - LineGraphic - Head - - ID - 11 - - ID - 22 - Points - - {615.59997809265133, 366.19994713914173} - {615.59997809265133, 317.79997613881233} - - Style - - stroke - - Color - - b - 0.398864 - g - 0.398857 - r - 0.398869 - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 3 - - - Tail - - ID - 12 - - - - Class - LineGraphic - Head - - ID - 11 - - ID - 21 - Points - - {494.61477487940653, 366.69121795377214} - {578.18521130589625, 317.30870532418186} - - Style - - stroke - - Color - - b - 0.398864 - g - 0.398857 - r - 0.398869 - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 3 - - - Tail - - ID - 10 - - - - Class - LineGraphic - Head - - ID - 9 - - ID - 20 - Points - - {457.20000809265139, 366.19994713914173} - {457.20000809265139, 317.79997613881233} - - Style - - stroke - - Color - - b - 0.398864 - g - 0.398857 - r - 0.398869 - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 3 - - - Tail - - ID - 10 - - - - Class - LineGraphic - Head - - ID - 9 - - ID - 19 - Points - - {336.21477455286674, 366.69121799294936} - {419.78521819920854, 317.30870528500463} - - Style - - stroke - - Color - - b - 0.398864 - g - 0.398857 - r - 0.398869 - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 3 - - - Tail - - ID - 6 - - - - Class - LineGraphic - Head - - ID - 5 - - ID - 16 - Points - - {298.79999165942382, 366.19994713698696} - {298.79999165942382, 317.79998366176108} - - Style - - stroke - - Color - - b - 0.398864 - g - 0.398857 - r - 0.398869 - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 3 - - - Tail - - ID - 6 - - - - Bounds - {{475.19997809265135, 460.80004713897705}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - FontInfo - - Color - - b - 0.298039 - g - 0.298039 - r - 0.298039 - - - ID - 15 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;\red76\green76\blue76;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf2 fixnum} - - - - Bounds - {{712.79998809265135, 273.59998713897704}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - ID - 13 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - FillType - 2 - GradientAngle - 90 - GradientColor - - b - 0.6 - g - 0.6 - r - 0.6 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf0 void} - - - - Bounds - {{554.39995809265133, 367.19994713897705}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - ID - 12 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - FillType - 2 - GradientAngle - 90 - GradientColor - - b - 0.6 - g - 0.6 - r - 0.6 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf0 unsigned} - - - - Bounds - {{554.39998809265137, 273.59998713897704}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - ID - 11 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - FillType - 2 - GradientAngle - 90 - GradientColor - - b - 0.6 - g - 0.6 - r - 0.6 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf0 int} - - - - Bounds - {{395.99999809265137, 367.19994713897705}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - FontInfo - - Color - - b - 0.298039 - g - 0.298039 - r - 0.298039 - - - ID - 10 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;\red76\green76\blue76;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf2 signed} - - - - Bounds - {{395.99999809265137, 273.59998713897704}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - FontInfo - - Color - - b - 0.298039 - g - 0.298039 - r - 0.298039 - - - ID - 9 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;\red76\green76\blue76;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf2 extern} - - - - Bounds - {{395.99999809265137, 179.99999713897705}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - ID - 8 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - FillType - 2 - GradientAngle - 90 - GradientColor - - b - 0.6 - g - 0.6 - r - 0.6 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf0 intish} - - - - Bounds - {{237.59999465942383, 367.19994713897705}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - FontInfo - - Color - - b - 0.298039 - g - 0.298039 - r - 0.298039 - - - ID - 6 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;\red76\green76\blue76;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf2 double} - - - - Bounds - {{237.59999465942383, 273.59999465942383}, {122.40000000000001, 43.199989000000002}} - Class - ShapedGraphic - ID - 5 - Shape - Rectangle - Style - - fill - - Color - - b - 0.901961 - g - 0.901961 - r - 0.901961 - - FillType - 2 - GradientAngle - 90 - GradientColor - - b - 0.6 - g - 0.6 - r - 0.6 - - - shadow - - Draws - NO - - stroke - - Color - - b - 0.4 - g - 0.4 - r - 0.4 - - CornerRadius - 5 - Width - 2 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Calibri;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\b\fs28 \cf0 double?} - - - - GridInfo - - GridSpacing - 7.1999998092651367 - MajorGridSpacing - 10 - ShowsGrid - YES - SnapsToGrid - YES - - GuidesLocked - NO - GuidesVisible - YES - HPages - 2 - ImageCounter - 1 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - LinksVisible - NO - MagnetsVisible - NO - MasterSheets - - ModificationDate - 2014-06-30 23:06:41 +0000 - Modifier - David Herman - NotesVisible - NO - Orientation - 2 - OriginVisible - NO - PageBreaks - YES - PrintInfo - - NSBottomMargin - - float - 41 - - NSHorizonalPagination - - int - 0 - - NSLeftMargin - - float - 18 - - NSPaperSize - - size - {612, 792} - - NSPrintReverseOrientation - - int - 0 - - NSRightMargin - - float - 18 - - NSTopMargin - - float - 18 - - - PrintOnePage - - ReadOnly - NO - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - SmartAlignmentGuidesActive - YES - SmartDistanceGuidesActive - YES - UniqueID - 1 - UseEntirePage - - VPages - 1 - WindowInfo - - CurrentSheet - 0 - ExpandedCanvases - - - name - Canvas 1 - - - Frame - {{40, 4}, {1175, 742}} - ListView - - OutlineWidth - 142 - RightSidebar - - ShowRuler - - Sidebar - - SidebarWidth - 120 - VisibleRegion - {{0, 0}, {1040, 603}} - Zoom - 1 - ZoomValues - - - Canvas 1 - 1 - 2 - - - - - diff --git a/html/subtypes.png b/html/subtypes.png deleted file mode 100644 index 41ea3a4..0000000 Binary files a/html/subtypes.png and /dev/null differ diff --git a/html/whatwg.css b/html/whatwg.css deleted file mode 100644 index 395f7c4..0000000 --- a/html/whatwg.css +++ /dev/null @@ -1,287 +0,0 @@ -/* WHATWG Green: sRGB #3c790a, rgb(60, 121, 10) */ - -html { margin: 0; padding: 0; color: black; background: white; } -body { margin: 0; padding: 0 1em 2em 8.5em; line-height: 1.35; color: black; background: white top left repeat-y; } - -@media screen { - html { background: #eeeeee; } - body { margin-bottom: 30%; border-bottom: thin solid #3c790a; } -} - -:link { color: #00C; background: transparent } -:visited { color: #609; background: transparent } -:link:active, :visited:active { color: #C00; background: transparent } -:link:hover, :visited:hover { background: #ffa; } -code :link, code :visited { color: inherit; } - -body, th, td { font-family: sans-serif, Droid Sans Fallback; } - -h1, h2, h3, h4, h5, h6 { text-align: left; text-rendering: optimiseLegibility; } -h1, h2, h3 { color: #3c790a; background: transparent; } -h1 { font: 900 200% sans-serif, Droid Sans Fallback; } -h1.allcaps { font: 900 350% sans-serif, Droid Sans Fallback; letter-spacing: 2px; } -h2 { font: 800 140% sans-serif, Droid Sans Fallback; } -h3 { font: 800 125% sans-serif, Droid Sans Fallback; } -h4 { font: 800 110% sans-serif, Droid Sans Fallback; } -h5 { font: 800 100% sans-serif, Droid Sans Fallback; } -h6 { font: 600 italic 100% sans-serif, Droid Sans Fallback; } - -pre { margin-left: 2em; white-space: pre-wrap; } -h2 { margin: 3em 0 1em 0; } -h3 { margin: 2.5em 0 1em 0; } -h4 { margin: 2.5em 0 0.75em 0; } -h5, h6 { margin: 2.5em 0 1em; } -h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6, h1 + div + h2, h2 + div + h3, h3 + div + h4, h4 + div + h5, h5 + div + h6 { margin-top: 0.5em; } -p { margin: 1em 0; } -hr { display: block; background: none; border: none; padding: 0; margin: 2em 0; height: auto; } -dl, dd { margin-top: 0; margin-bottom: 0; } -dt { margin-top: 0.75em; margin-bottom: 0.25em; clear: left; } -dt + dt { margin-top: 0; } -dd dt { margin-top: 0.25em; margin-bottom: 0; } -dd p, dd ol, dd ol.brief { margin-top: 0; } -dd dl + p { margin-top: 1em; } -dd table + p { margin-top: 1em; } -p + * > li, dd li { margin: 1em 0; } -dt, dfn { font-weight: bold; font-style: normal; } -i, em, dt dfn { font-style: italic; } -pre, code { font-size: inherit; font-family: monospace, Droid Sans Fallback, sans-serif; font-variant: normal; } -pre strong { color: black; font: inherit; font-weight: bold; background: #B7EDEA; } -pre em { font-weight: bolder; font-style: normal; } -@media screen { code { color: orangered; } } -var sub { vertical-align: bottom; font-size: smaller; position: relative; top: 0.1em; } -table { border-collapse: collapse; border-style: hidden hidden none hidden; } -table thead, table tbody { border-bottom: solid; } -table tbody th { text-align: left; } -table tbody th:first-child { border-left: solid; } -table td, table th { border-left: solid; border-right: solid; border-bottom: solid thin; vertical-align: top; padding: 0.2em; } -blockquote { margin: 0 0 0 2em; border: 0; padding: 0; font-style: italic; } -ins { background: green; color: white; /* color: green; border: solid thin lime; padding: 0.3em; line-height: 1.6em; */ text-decoration: none; } -del { background: maroon; color: white; /* color: maroon; border: solid thin red; padding: 0.3em; line-height: 1.6em; */ text-decoration: line-through; } -body ins, body del { display: block; } -body * ins, body * del { display: inline; } - -.toc dfn, h1 dfn, h2 dfn, h3 dfn, h4 dfn, h5 dfn, h6 dfn { font: inherit; } -img.extra, p.overview { float: right; } -hr.bookmark { border: dashed 2em black; background: yellow; } -pre::before { font: bold 0.8em sans-serif; padding: 0.5em; position: absolute; top: auto; margin: -0.703125em 0 0 -3.75em /* 1em/0.8 + 1.5em + 0.5em*2 */ ; width: 1.5em; background: inherit; border: 0.078125em; border-style: solid none solid solid; border-radius: 1em 0 0 1em; } -pre.idl { border: solid 0.0625em; background: #EEEEEE; color: black; padding: 0.5em 1em; } -pre.idl :link, pre.idl :visited { color: inherit; background: transparent; } -pre.idl::before { content: 'IDL'; } -pre.asn { border: solid 0.0625em; background: #EEEEEE; color: black; padding: 0.5em 1em; } -pre.asn :link, pre.asn :visited { color: inherit; background: transparent; } -pre.asn::before { content: 'ASN'; } -pre.css { border: solid 0.0625em; background: #FFFFEE; color: black; padding: 0.5em 1em; } -pre.css:first-line { color: #AAAA50; } -pre.css::before { content: 'CSS'; } -dl.domintro { color: green; margin: 2em 0 2em 0; padding: 0.5em 1em 0.5em 2em; border: none; background: #DDFFDD; } -hr + dl.domintro, div.impl + dl.domintro { margin-top: 2.5em; margin-bottom: 1.5em; } -dl.domintro dt, dl.domintro dt * { color: black; text-decoration: none; } -dl.domintro dd { margin: 0.5em 0 1em 2em; padding: 0; } -dl.domintro dd p { margin: 0.5em 0; } -dl.domintro:before { display: table; margin: -1em -0.5em -0.5em auto; width: auto; content: 'This box is non-normative. Implementation requirements are given below this box.'; color: black; font-style: italic; border: solid 2px; background: white; padding: 0 0.25em; } -dl.switch { padding-left: 2em; } -dl.switch > dt { text-indent: -1.5em; } -dl.switch > dt:before { content: '\21AA'; padding: 0 0.5em 0 0; display: inline-block; width: 1em; text-align: right; line-height: 0.5em; } -dl.triple { padding: 0 0 0 1em; } -dl.triple dt, dl.triple dd { margin: 0; display: inline } -dl.triple dt:after { content: ':'; } -dl.triple dd:after { content: '\A'; white-space: pre; } -.diff-old { text-decoration: line-through; color: silver; background: transparent; } -.diff-chg, .diff-new { text-decoration: underline; color: green; background: transparent; } -a .diff-new { border-bottom: 1px blue solid; } -tr.rare { background: #EEEEEE; color: #333333; } - -figure.diagrams { border: double black; background: white; padding: 1em; } -figure.diagrams img { display: block; margin: 1em auto; } - -h2 { page-break-before: always; } -h1, h2, h3, h4, h5, h6, dt { page-break-after: avoid; } -h1 + h2, hr + h2.no-toc { page-break-before: auto; } - -p > span:not([title=""]):not([class="XXX"]):not([class="impl"]):not([class="note"]), -li > span:not([title=""]):not([class="XXX"]):not([class="impl"]):not([class="note"]) { border-bottom: solid #99CC99; } - -.head { margin: 0 0 1em; padding: 1em 0 0 0; display: block; } -.head p { margin: 0; } -.head h1 { margin: 0; } -.head h2 { margin-top: 0; } -.head .logo { float: right; margin: 0 1em; } -.head .logo img { display: block; margin: 0 0 0 auto; border: none } /* remove border from top image */ -.head dl { margin: 1em 0; } -p.copyright { font-size: 0.6em; font-style: oblique; margin: 0; } - -body > .toc > li { margin-top: 1em; margin-bottom: 1em; } -body > .toc.brief > li { margin-top: 0.35em; margin-bottom: 0.35em; } -body > .toc > li > * { margin-bottom: 0.5em; } -body > .toc > li > * > li > * { margin-bottom: 0.25em; } -.toc, .toc li { list-style: none; } - -.brief { margin-top: 1em; margin-bottom: 1em; line-height: 1.1; } -.brief > li { margin: 0; padding: 0; } -.brief > li > p { margin: 0; padding: 0; } - -.category-list { margin-top: -0.75em; margin-bottom: 1em; line-height: 1.5; } -.category-list::before { content: '\21D2\A0'; font-size: 1.2em; font-weight: 900; } -.category-list li { display: inline; } -.category-list li:not(:last-child)::after { content: ', '; } -.category-list li > span, .category-list li > a { text-transform: lowercase; } -.category-list li * { text-transform: none; } /* don't affect nested in */ - -[title=WIP], [title=TBW] { background: red; color: yellow; padding: 0.1em 0.3em; border: dotted white; margin: 0 0.7em 0 0.2em; } -[title=SCS] { background: green; color: white; padding: 0.1em 0.3em; border-style: none dashed; margin: 0 0.7em 0 0.2em; } -[title=WIP] :link, [title=WIP] :visited, -[title=TBW] :link, [title=TBW] :visited, -[title=SCS] :link, [title=SCS] :visited { background: transparent; color: inherit; } - -.big-issue, .XXX { color: #E50000; background: white; border: solid red; padding: 0.5em; margin: 1em 0; } -.big-issue > :first-child, .XXX > :first-child { margin-top: 0; } -p .big-issue, p .XXX { line-height: 3em; } -.note { color: green; background: transparent; font-family: sans-serif, Droid Sans Fallback; } -.warning { color: red; background: transparent; } -.note, .warning { font-weight: bolder; font-style: italic; } -.note em, .warning em, .note i, .warning i, .note var, .warning var { font-style: normal; } -p.note, div.note { padding: 0.5em 2em; } -span.note { padding: 0 2em; } -.note p:first-child, .warning p:first-child { margin-top: 0; } -.note p:last-child, .warning p:last-child { margin-bottom: 0; } -dd > .note:first-child { margin-bottom: 0; } -.warning:before { font-style: normal; } - -.tablenote { margin: 0.25em 0; } -.tablenote small { font-size: 0.9em; } - -.XXX:before, .XXX:after { content: " ** "; position: absolute; left: 0; width: 8em; text-align: right; } -p.note:before { content: 'Note: '; } -p.warning:before { content: '\26A0 Warning! '; } - -.bookkeeping:before { display: block; content: 'Bookkeeping details'; font-weight: bolder; font-style: italic; } -.bookkeeping { font-size: 0.8em; margin: 2em 0; } -.bookkeeping p { margin: 0.5em 2em; display: list-item; list-style: square; } -.bookkeeping dt { margin: 0.5em 2em 0; } -.bookkeeping dd { margin: 0 3em 0.5em; } - -.critical { margin: 1em; border: double thick red; padding: 1em; background: #FFFFCC; } -.critical > :first-child { margin-top: 0; } - -h4 { position: relative; z-index: 3; } -h4 + .element, h4 + div + .element { margin-top: -2.5em; padding-top: 2em; } -.element { background: #EEFFEE; color: black; margin: 0 0 1em 0.15em; padding: 0 1em 0.25em 0.75em; border-left: solid #99FF99 0.25em; position: relative; z-index: 1; } -.element:before { position: absolute; z-index: 2; top: 0; left: -1.15em; height: 2em; width: 0.9em; background: #EEFFEE; content: ' '; border-style: none none solid solid; border-color: #99FF99; border-width: 0.25em; } -.element:not(:hover) > dt > :link, .element:not(:hover) > dt > :visited { color: inherit; text-decoration: none; } - -table.css-property caption { text-align: left; font: inherit; font-weight: bold; } -table.css-property th { font: inherit; font-style: italic; text-align: left; padding-left: 2em; } - -.example { display: block; color: #222222; background: #FCFCFC; border-left: double; margin-left: 2em; padding-left: 1em; } -td > .example:only-child { margin: 0 0 0 0.1em; } - -td.non-rectangular-cell-continuation { border-left-style: hidden; } -td.non-rectangular-cell-indentation { border-top-style: hidden; min-width: 2em; } - -.hide { display: none } - -body.dfnEnabled dfn { cursor: pointer; } -.dfnPanel { - display: inline; - position: absolute; - z-index: 10; - height: auto; - width: auto; - padding: 0.5em 0.75em; - font: small sans-serif, Droid Sans Fallback; - background: #DDDDDD; - color: black; - border: outset 0.2em; -} -.dfnPanel * { margin: 0; padding: 0; font: inherit; text-indent: 0; } -.dfnPanel :link, .dfnPanel :visited { color: black; } -.dfnPanel p { font-weight: bolder; } -.dfnPanel * + p { margin-top: 0.25em; } -.dfnPanel li { list-style-position: inside; } - -@media aural { - h1, h2, h3 { stress: 20; richness: 90 } - .hide { speak: none } - p.copyright { volume: x-soft; speech-rate: x-fast } - dt { pause-before: 20% } - code, pre { speak-punctuation: code } -} - -@media print { - html { font-size: 8pt; } - @page { margin: 1cm 1cm 1cm 1cm; } - @page :left { - @bottom-left { - font: 6pt sans-serif, Droid Sans Fallback; - content: counter(page); - padding-top: 0em; - vertical-align: top; - } - } - @page :right { - @bottom-right { - font: 6pt sans-serif, Droid Sans Fallback; - content: counter(page); - text-align: right; - vertical-align: top; - padding-top: 0em; - } - } - a[href^="#"]::after { font-size: 0.6em; vertical-align: super; padding: 0 0.15em 0 0.15em; content: "p" target-counter(attr(href), page); } - .toc a::after { font: inherit; vertical-align: baseline; padding: 0; content: leader('.') target-counter(attr(href), page); } - pre a[href^="#"]::after, blockquote a[href^="#"]::after { content: ""; padding: 0; } - table { font-size: smaller; } - :link, :visited { text-decoration: none; color: inherit; background: transparent; } -} - -ul.domTree, ul.domTree ul { padding: 0 0 0 1em; margin: 0; } -ul.domTree li { padding: 0; margin: 0; list-style: none; position: relative; } -ul.domTree li li { list-style: none; } -ul.domTree li:first-child::before { position: absolute; top: 0; height: 0.6em; left: -0.75em; width: 0.5em; border-style: none none solid solid; content: ''; border-width: 0.1em; } -ul.domTree li:not(:last-child)::after { position: absolute; top: 0; bottom: -0.6em; left: -0.75em; width: 0.5em; border-style: none none solid solid; content: ''; border-width: 0.1em; } -ul.domTree span { font-style: italic; font-family: serif, Droid Sans Fallback; } -ul.domTree .t1 code { color: purple; font-weight: bold; } -ul.domTree .t2 { font-style: normal; font-family: monospace, Droid Sans Fallback; } -ul.domTree .t2 .name { color: black; font-weight: bold; } -ul.domTree .t2 .value { color: blue; font-weight: normal; } -ul.domTree .t3 code, .domTree .t4 code, .domTree .t5 code { color: gray; } -ul.domTree .t7 code, .domTree .t8 code { color: green; } -ul.domTree .t10 code { color: teal; } - -:target { - background: #ffa; - -moz-box-shadow: 0 0 25px #ffa; - -webkit-box-shadow: 0 0 150px #ffa; - box-shadow: 0 0 25px #ffa; -} - -/*body:not(.statusEnabled) .head, body:not(.dfnEnabled) .head { background: bottom right url(http://hixie.ch/resources/images/spinner) no-repeat; }*/ - -div.compilation:before { - content: "Compilation"; - font: bold small sans-serif; - /*float: left;*/ - position: absolute; - top: -0.9em; - left: -2.5em; - width: 7.5em; - text-align: center; - line-height: 1em; - color: #F8FFDD; - background: #060; - padding: 0.1em; - border: thin solid #999; - /*margin: -1.3em 0 0.3em -2.5em;*/ -} -div.compilation, pre.compilation { - background: #F8FFDD; - padding: 0.5em; - margin: 1em 0; - border: thin solid #999; - position: relative; -} -pre.compilation { - padding-top: 1.5em; -} -div.compilation { color: #060 } -pre.compilation { color: #060 } diff --git a/lib/validate.js b/lib/validate.js index 3d0649a..dc95adf 100644 --- a/lib/validate.js +++ b/lib/validate.js @@ -745,7 +745,7 @@ Vp.doWhileStatement = function doWhileStatement(body, test) { // (VariableDeclaration | Expression | null, Expression | null, Expression | null, Statement, Loc) -> void Vp.forStatement = function forStatement(init, test, update, body, loc) { - if (init.type === 'VariableDeclaration') + if (init !== null && init.type === 'VariableDeclaration') this.fail("illegal variable declaration in for-head", init.loc); this.optExpression(init); this.checkSubtype(this.optExpression(test) || ty.Int, ty.Int, "for loop condition", loc); @@ -865,10 +865,18 @@ Vp.expression = function expression(e) { this.checkSubtype(this.expression(vars.test), ty.Int, "conditional test", vars.test.loc); var t1 = this.expression(vars.cons); var t2 = this.expression(vars.alt); - if (t1 !== t2) - this.fail("type mismatch between conditional branches", e.loc); - if (t1 !== ty.Int && t1 !== ty.Double) + + var t1supertype; + if (t1.subtype(ty.Int)) { + t1supertype = ty.Int; + } else if (t1.subtype(ty.Double)) { + t1supertype = ty.Double; + } else { this.fail("expected int or double in conditional branch, got " + t1, vars.cons.loc); + } + + if (!t2.subtype(t1supertype)) + this.fail("type mismatch between conditional branches", e.loc); return t1; }, this); diff --git a/test/index.js b/test/index.js index aa43a0d..a787115 100644 --- a/test/index.js +++ b/test/index.js @@ -301,3 +301,56 @@ exports.testFunctionTables = asmAssert( var x = [f], y = [g], z = [f, g] return f; }, { pass: true }); + +exports.testConditionalExpression = asmAssert.one( + "conditional expression", + function f() { + return (1 ? 2 : 3)|0; + }, + { pass: true }); + +exports.testConditionalExpressionMismatchedTypes = asmAssert.one( + "conditional with consequent and alternate of differing types", + function f() { + return (1 ? 0.5 : 3)|0; + }, + { pass: false }); + +exports.testConditionalExpressionDifferentSubtypes = asmAssert.one( + "conditional with different subtypes of int", + function f() { + return (1 ? (2 < 3) : 4)|0; + }, + { pass: true }); + +exports.testForWithoutInit = asmAssert.one( + "for statement without an init clause", + function f() { + var i = 0, j = 0; + for (; i|0 < 10; i = i|0 + 1) { + j = j|0 + i; + } + }, + { pass: true }); + +exports.testForWithoutTest = asmAssert.one( + "for statement without a test clause", + function f() { + var i = 0, j = 0; + for (i = 0; ; i = i|0 + 1) { + if (i|0 >= 10) break; + j = j|0 + i; + } + }, + { pass: true }); + +exports.testForWithoutUpdate = asmAssert.one( + "for statement without an update clause", + function f() { + var i = 0, j = 0; + for (i = 0; i|0 < 10;) { + j = j|0 + i; + i = i|0 + 1; + } + }, + { pass: true });