5.10 Data types: Structured Data and Heap Allocation
5.10.1 Preface: What’s wrong with Exprs-Lang v7
Exprs-lang v7 gained proper data types and algebraic expressions,
which is a huge step forward in expressivity and high-level reasoning.
However, it still does not allow us to express structured data.
Real languages require structured data—
To express data larger than a single word, we need support from the low-level languages to get access to locations larger than a single word in size. All our locations so far, registers and frame locations, are only a single word in size. We need access to heap pointers, memory locations whose size can be arbitrary.
(alloc e) allocates a number of bytes specified by e and returns a pointer to the base address of those bytes.
(mref e_base e_index) dereferences the pointer at e_base with the offset specified by e_index. Thinking in terms of pointer arithmetic, this dereferences (+ e_base e_index). The value of (+ e_base e_index) should always be word-aligned, i.e., a multiple of 8, and point to a an initialized heap allocated value.
(mset! e_base e_index e) stores the value of e in the address (+ e_base e_index), i.e., in the address given by pointer at e_base with the offset specified by e_index. The value of (+ e_base e_index) should always be word-aligned, i.e., a multiple of 8.
To implement these new memory operations, or mops (pronounced em ops), we need to expose additional features from x64.
5.10.2 Exposing Heap Pointers in the Back-end
5.10.2.1 generate-x64
We start by exposing a generalized addr form in Paren-x64 v8 below, which will allow us to access arbitrary memory locations.
| p | ::= | (begin s ...) | ||
| s | ::= | (set! addr int32) | ||
| | | (set! addr trg) | |||
| | | (set! reg loc) | |||
| | | (set! reg triv) | |||
| | | (set! reg_1 (binop reg_1 int32)) | |||
| | | (set! reg_1 (binop reg_1 loc)) | |||
| | | (with-label label? s) | |||
| | | (jump trg) | |||
| | | (compare reg opand) | |||
| | | (jump-if relop label) | |||
| trg | ::= | reg | ||
| | | label | |||
| triv | ::= | trg | ||
| | | int64 | |||
| opand | ::= | int64 | ||
| | | reg | |||
| loc | ::= | reg | ||
| | | addr | |||
| addr | ::= | (fbp - dispoffset) | ||
| | | (reg + int32) | |||
| | | (reg + reg) |
| p | ::= | (begin s ...) | ||
| s | ::= | (set! addr int32) | ||
| | | (set! addr trg) | |||
| | | (set! reg loc) | |||
| | | (set! reg triv) | |||
| | | (set! reg_1 (binop reg_1 int32)) | |||
| | | (set! reg_1 (binop reg_1 loc)) | |||
| | | (with-label label? s) | |||
| | | (jump trg) | |||
| | | (compare reg opand) | |||
| | | (jump-if relop label) | |||
| trg | ::= | reg | ||
| | | label | |||
| triv | ::= | trg | ||
| | | int64 | |||
| opand | ::= | int64 | ||
| | | reg | |||
| loc | ::= | reg | ||
| | | addr | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r10 | |||
| | | r11 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| addr | ::= | (fbp - dispoffset) | ||
| | | (reg + int32) | |||
| | | (reg + reg) | |||
| fbp | ::= | frame-base-pointer-register? | ||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int32 | ::= | int32? | ||
| int64 | ::= | int64? | ||
| label | ::= | label? | ||
| dispoffset | ::= | dispoffset? |
The language contains a new addr representing the x64 index-mode operand (reg + reg). This supports accessing a memory location by the index stored in another register. For example, in x64, we represent loading the nth element of an array into r10 using mov r10 [r11 + r12], where the base of the array is stored at r11 and the value of n is stored in r12.
The index-mode operand is not restricted to use a particular register, unlike the displacement-mode operand from Paren-x64 v7. We will use this feature to store pointers to structured data, and the register allocator will move those pointers into whichever registers it chooses.
We also allow a generalized form of displacement-mode operand. We can access the value pointed to by a base register reg at offset int32. by (reg + int32). This allows optimizing heap accesses when a constant offset is known, which is often the case for some data structures. The index is not restricted to be a multiple of 8, but it should be the case in our compiler that the value of the base plus the value of the offset is a multiple of 8.
All languages with direct access to registers, including Paren-x64 v8, are now parameterized by a new register, current-heap-base-pointer-register (abbreviated hbp). The run-time system initializes this register to point to the base of the heap. Allocation is implemented by copying the current value of this pointer, and incrementing it by the number of bytes we wish to allocate. The pointer must only be incremented by word-size multiples of bytes. Any other access to this register is now undefined behavior, similar to accesses to fbp that do not obey the stack of frames discipline.
Design digression:A real language implementation might abstract access to the mmap system call for allocation, and implement a strategy (such as garbage collection) to deallocate memory that is no longer used. Garbage collection is tricky to implement and requires too much time for this course, so we use a different strategy. Our implementation of allocation is trivial, and does not support de-allocation. We rely on the operating system to clean up memory after our process exits.For a quick introduction to garbage collection, see this short video https://twitter.com/TartanLlama/status/1296413612907663361?s=20.
procedure
(generate-x64 s) → string?
s : paren-x64-v8
5.10.2.2 Em-Ops: Abstracting Memory Operations
Like when we implemented fvars to support working with frame locations, we implement primitive memory operations, mops , to simplify working with heap addresses. We should do this before patch-instructions to avoid complicating the already complex logic for rewriting set! instructions.
Below, we define Paren-x64-mops v8, with differences compared to Paren-x64-v8.
| p | ::= | (begin s ...) | ||
| s | ::= | (set! addr int32) | ||
| | | (set! addr trg) | |||
| | | (set! reg loc) | |||
| | | (set! reg triv) | |||
| | | (set! reg_1 (binop reg_1 int32)) | |||
| | | (set! reg_1 (binop reg_1 loc)) | |||
| | | (set! reg_1 (mref reg_2 index)) | |||
| | | (mset! reg_1 index triv) | |||
| | | (with-label label label? s) | |||
| | | (jump trg) | |||
| | | (compare reg opand) | |||
| | | (jump-if relop label) | |||
| addr | ::= | (fbp - dispoffset) |
| p | ::= | (begin s ...) | ||
| s | ::= | (set! addr int32) | ||
| | | (set! addr trg) | |||
| | | (set! reg loc) | |||
| | | (set! reg triv) | |||
| | | (set! reg_1 (binop reg_1 int32)) | |||
| | | (set! reg_1 (binop reg_1 loc)) | |||
| | | (set! reg_1 (mref reg_2 index)) | |||
| | | (mset! reg_1 index triv) | |||
| | | (with-label label s) | |||
| | | (jump trg) | |||
| | | (compare reg opand) | |||
| | | (jump-if relop label) | |||
| trg | ::= | reg | ||
| | | label | |||
| triv | ::= | trg | ||
| | | int64 | |||
| opand | ::= | int64 | ||
| | | reg | |||
| loc | ::= | reg | ||
| | | addr | |||
| index | ::= | int32 | ||
| | | reg | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r10 | |||
| | | r11 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| addr | ::= | (fbp - dispoffset) | ||
| fbp | ::= | frame-base-pointer-register? | ||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| label | ::= | label? | ||
| dispoffset | ::= | dispoffset? |
We could encode the restricted form of addr, used for frame variables, as an mref, but the rest of our compiler already knows about addrs, and it represents a semantically different concept, so we leave it alone.
procedure
(implement-mops p) → paren-x64-v8?
p : paren-x64-mops-v8?
Next we design Para-asm-lang v8. Below, we give a definition.
| p | ::= | (begin s ...) | ||
| s | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc_1 index triv) | |||
| | | (with-label label s) | |||
| | | (jump trg) | |||
| | | (compare loc opand) | |||
| | | (jump-if relop trg) | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | reg | ||
| | | addr | |||
| index | ::= | int64 | ||
| | | loc | |||
| addr | ::= | (fbp - dispoffset) | ||
| fbp | ::= | frame-base-pointer-register? | ||
| int32 | ::= | int32? | ||
| dispoffset | ::= | dispoffset? |
| p | ::= | (begin s ...) | ||
| s | ::= | (set! addr int32) | ||
| | | (set! addr trg) | |||
| | | (set! reg loc triv) | |||
| | | (set! reg triv) | |||
| | | (set! loc_1 reg_1 (binop loc_1 opand reg_1 int32)) | |||
| | | (set! reg_1 (binop reg_1 loc)) | |||
| | | (set! loc_1 reg_1 (mref loc_2 reg_2 index)) | |||
| | | (mset! loc_1 reg_1 index triv) | |||
| | | (with-label label s) | |||
| | | (jump trg) | |||
| | | (compare loc reg opand) | |||
| | | (jump-if relop trg label) | |||
| trg | ::= | reg | ||
| | | label | |||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| | | trg | |||
| | | int64 | |||
| opand | ::= | int64 | ||
| | | loc | |||
| | | reg | |||
| loc | ::= | reg | ||
| | | addr | |||
| index | ::= | int64 | ||
| | | loc | |||
| | | int32 | |||
| | | reg | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r10 | |||
| | | r11 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| addr | ::= | (fbp - dispoffset) | ||
| fbp | ::= | frame-base-pointer-register? | ||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| label | ::= | label? | ||
| dispoffset | ::= | dispoffset? |
| p | ::= | (begin s ...) | ||
| s | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc_1 index triv) | |||
| | | (with-label label s) | |||
| | | (jump trg) | |||
| | | (compare loc opand) | |||
| | | (jump-if relop trg) | |||
| trg | ::= | label | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| opand | ::= | int64 | ||
| | | loc | |||
| loc | ::= | reg | ||
| | | addr | |||
| index | ::= | int64 | ||
| | | loc | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| addr | ::= | (fbp - dispoffset) | ||
| fbp | ::= | frame-base-pointer-register? | ||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| label | ::= | label? | ||
| dispoffset | ::= | dispoffset? |
By introducing mops, we implicitly restrict how heap addresses appear in the language and simplify the job of patch-instructions. The mops implicitly restrict heap addresses to being part of a move instruction, so we do not have to patch binary operation instructions despite apparently adding a new form of physical location. By making them separate forms, we only need to patch the new instructions, and leave old code untouched.
In patch-instructions, we also lift the restriction on index, so int64s can appear as an index. This makes index and opand coincide, syntactically, but they are conceptually different so we maintain separate non-terminal definitions.
procedure
s : para-asm-lang-v8
5.10.2.3 Exposing mops up the pipeline
The new mops require minor changes to most of the pipeline up to Asm-alloc-lang v8, where we will use them to implement data structures.
Exercise 9: Redesign and extend the implementation of
flatten-program, should require no changes
resolve-predicates, should require no changes
expose-basic-blocks, should require no changes
implement-fvars, should require minor changes to support mops. Note that we assume the fbp is not modified by mops.
optimize-predicates, could require minor changes.
replace-locations, should require minor changes to support mops.
assign-frame-variables, should require no changes.
assign-registers, should require no changes.
allocate-frames, should require no changes.
assign-call-undead-variables, should require no changes.
conflict-analysis, should require minor changes. Note that mops do not assign any registers or frame variables.
undead-analysis, should require minor changes. Note that mops do not assign any registers or frame variables.
uncover-locals, should require minor changes.
5.10.2.4 Implementing Allocation
Before we introduce structured data, we implement the alloc instruction to allow programs to allocate a bunch of bytes and not worry about the details of the allocation pointer. We want to do this after the passes that analyze physical locations, since then we do not have to update those passes to know that alloc introduces a reference to a register. However, we want to do this before we abstract away from all machine details so we do not need to expose registers beyond Asm-alloc-lang v8.
We choose to insert this pass between uncover-locals and select-instructions.
Below, we design Asm-alloc-lang v8, the source language for this pass. We typeset the differences compared to Asm-pred-lang v7.
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (set! loc (alloc index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| index | ::= | int64 | ||
| | | loc | |||
| int32 | ::= | int32? |
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (set! loc (alloc index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
We expose the earlier mops, and add a new one, (set! loc (alloc index)). This is the low-level form of our allocation operation, which we will abstract into an expression in Exprs-lang v8. In (set! loc (alloc index)), the index is restricted to be an int32 if it is an integer literal, for the same reasons as the restriction on binops. It must also be a multiple of a word size. This requirement is partly from the operating system’s mmap (which will usually ignore us if we violate the restriction and give us page-aligned memory anyway), but mostly to ensure every pointer we get has #b000 as its final three bits so we can tag all pointers.
We design the target language, Asm-pred-lang v8, below. This language removes the (alloc index) form and is the highest-level language parameterized by current-heap-base-pointer-register. This language, and all languages between it and x64, assumes all accesses to hbp obey the restrictions described in Paren-x64 v8.
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (set! loc (alloc index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| index | ::= | int64 | ||
| | | loc |
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| index | ::= | int64 | ||
| | | loc | |||
| int32 | ::= | int32? |
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
`(begin (set! ,loc ,hbp) (set! ,hbp (+ ,hbp ,index)))
procedure
p : asm-alloc-lang-v8?
5.10.2.5 Abstracting Mops
Before we implement structured data, we expose our mops through a few layers of abstractions. Below we design Imp-cmf-lang v8 with support for mops. We typeset the differences compared to Imp-cmf-lang v7.
| p | ::= | (module info (define label info tail) ... tail) | ||
| pred | ::= | (relop opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref loc opand) | |||
| | | (alloc opand) | |||
| effect | ::= | (set! loc value) | ||
| | | (mset! loc opand triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) |
| p | ::= | (module info (define label info tail) ... tail) | ||
| pred | ::= | (relop loc opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref loc opand) | |||
| | | (alloc opand) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (set! loc (alloc index) value) | |||
| | | (mset! loc index opand triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| index | ::= | int64 | ||
| | | loc | |||
| int32 | ::= | int32? |
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref loc opand) | |||
| | | (alloc opand) | |||
| effect | ::= | (set! loc value) | ||
| | | (mset! loc opand triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
We add value forms of mref and alloc. We require these forms are used in a well-typed way. This is a simple extension.
procedure
p : imp-cmf-lang-v8?
Next we design Imp-mf-lang v8 with support for mops.
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref loc opand) | |||
| | | (alloc opand) | |||
| | | (begin effect ... value) | |||
| | | (if pred value value) | |||
| | | (return-point label tail) | |||
| effect | ::= | (set! loc value) | ||
| | | (mset! loc opand value) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) |
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref loc opand) | |||
| | | (alloc opand) | |||
| | | (begin effect ... value) | |||
| | | (if pred value value) | |||
| | | (return-point label tail) | |||
| effect | ::= | (set! loc value) | ||
| | | (mset! loc opand value) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
We introduce the value context, but notice that the index position for an mset! instruction is still restricted.
Question: Why can’t (or shouldn’t) we allow the index position to also be a value?
procedure
p : imp-mf-lang-v8?
(set! loc (begin effect_1 ... value)) | = | (begin effect_1 ... (set! loc value)) |
(set! loc (if pred value_1 value_2)) | = | (if pred (set! loc value_1) (set! loc value_2)) |
(mset! loc opand (begin effect_1 ... value)) | = | (begin effect_1 ... (mset! loc opand value)) |
(mset! loc opand (if pred value_1 value_2)) | = | (if pred (mset! loc opand value_1) (mset! loc opand value_2)) |
The impose-calling-conventions pass requires only minor changes.
For sequentialize-let, we need to design an effect context in order to expose mset!. We design Values-bits-lang v8 to include a few imperative features.
| p | ::= | (module (define label (lambda (aloc ...) tail)) ... tail) | ||
| pred | ::= | (relop opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (let ([aloc value] ...) pred) | |||
| | | (if pred pred pred) | |||
| | | (begin effect ... pred) | |||
| tail | ::= | value | ||
| | | (let ([aloc value] ...) tail) | |||
| | | (if pred tail tail) | |||
| | | (call triv opand ...) | |||
| | | (begin effect ... tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref aloc opand) | |||
| | | (alloc opand) | |||
| | | (let ([aloc value] ...) value) | |||
| | | (if pred value value) | |||
| | | (call triv opand ...) | |||
| | | (begin effect ... value) | |||
| effect | ::= | (mset! aloc opand value) | ||
| | | (let ([aloc value] ...) effect) | |||
| | | (begin effect ... effect) |
| p | ::= | (module (define label (lambda (aloc ...) entry tail)) ... entry tail) | ||
| entry | ::= | tail | ||
| pred | ::= | (relop opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (let ([aloc value] ...) pred) | |||
| | | (if pred pred pred) | |||
| | | (begin effect ... pred) | |||
| tail | ::= | value | ||
| | | (let ([aloc value] ...) tail) | |||
| | | (if pred tail tail) | |||
| | | (call triv opand ...) | |||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref aloc opand) | |||
| | | (alloc opand) | |||
| | | (begin effect ... value) | |||
| | | (let ([aloc value] ...) value) | |||
| | | (if pred value value) | |||
| | | (call triv opand ...) | |||
| | | (begin effect ... value) | |||
| effect | ::= | (set! aloc value) | ||
| | | (mset! aloc opand value) | |||
| | | (let ([aloc value] ...) effect) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) |
| p | ::= | (module (define label (lambda (aloc ...) tail)) ... tail) | ||
| pred | ::= | (relop opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (let ([aloc value] ...) pred) | |||
| | | (if pred pred pred) | |||
| | | (begin effect ... pred) | |||
| tail | ::= | value | ||
| | | (let ([aloc value] ...) tail) | |||
| | | (if pred tail tail) | |||
| | | (call triv opand ...) | |||
| | | (begin effect ... tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref aloc opand) | |||
| | | (alloc opand) | |||
| | | (let ([aloc value] ...) value) | |||
| | | (if pred value value) | |||
| | | (call triv opand ...) | |||
| | | (begin effect ... value) | |||
| effect | ::= | (mset! aloc opand value) | ||
| | | (let ([aloc value] ...) effect) | |||
| | | (begin effect ... effect) | |||
| opand | ::= | int64 | ||
| | | aloc | |||
| triv | ::= | opand | ||
| | | label | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? |
We add an effect context to support
mset!, and a begin expression for
convenience.
Previously, all expressions in the Values-lang languages were pure—
To deal with this, we introduce a contextual distinction in the language. We add the nonterminal effect to represent an impure computation. A effect represents an expression that does not have a value, and is executed only for its effect. We can use effect in certain expression contexts using begin. If we’re already in an impure context, that is, in a effect, then we can freely nest other effects.
This contextual distinction is similar to the one we introduce to distinguish tail calls from non-tail calls.
Despite the conceptually complex change to the language, the transformation is still straightforward.
Design digression:Now that effects can appear on the right-hand side of a let expression, it MAY not longer be safe to reorder them. This is a design choice: we could make it clear to the programmer that let does not guarantee a particular order of evaluation for its bindings, but then effects on the right-hand side lead to undefined behaviour. Or, we could impose a particular order, such as left-to-right, forbidding an optimization. A middle ground is to impose such an order only if any effects are detected in the right-hand side of a let (or rather, if we can guarantee no effects are present, because Rice still does not let us know for sure).
procedure
s : values-bits-lang-v8?
Finally, we enable arbitrary nesting in value position. We design Exprs-bits-lang v8/contexts below.
| p | ::= | (module b ... tail) | ||
| b | ::= | (define label (lambda (aloc ...) tail)) | ||
| pred | ::= | (relop value value) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (let ([aloc value] ...) pred) | |||
| | | (if pred pred pred) | |||
| | | (begin effect ... pred) | |||
| tail | ::= | value | ||
| | | (let ([aloc value] ...) tail) | |||
| | | (if pred tail tail) | |||
| | | (begin effect ... tail) | |||
| value | ::= | triv | ||
| | | (binop value value) | |||
| | | (mref value value) | |||
| | | (alloc value) | |||
| | | (call value value ...) | |||
| | | (let ([aloc value] ...) value) | |||
| | | (if pred value value) | |||
| | | (begin effect ... value) | |||
| effect | ::= | (mset! value value value) | ||
| | | (begin effect ... effect) |
| p | ::= | (module b ... tail) | ||
| b | ::= | (define label (lambda (aloc ...) tail)) | ||
| pred | ::= | (relop value value) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (let ([aloc value] ...) pred) | |||
| | | (if pred pred pred) | |||
| | | (begin effect ... pred) | |||
| tail | ::= | value | ||
| | | (let ([aloc value] ...) tail) | |||
| | | (if pred tail tail) | |||
| | | (begin effect ... tail) | |||
| value | ::= | triv | ||
| | | (binop value value) | |||
| | | (mref value value) | |||
| | | (alloc value) | |||
| | | (call value value ...) | |||
| | | (let ([aloc value]) value) | |||
| | | (if pred value value) | |||
| | | (begin effect ... value) | |||
| effect | ::= | (mset! value value value) | ||
| | | (begin effect ... effect) | |||
| triv | ::= | label | ||
| | | aloc | |||
| | | int64 | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? |
Supporting effect context requires paying attention to order when designing remove-complex-opera*, but does not significantly complicate anything.
procedure
p : exprs-bits-lang-v8/contexts?
5.10.2.6 Implementing Structured Data
Now we have all the abstractions necessary to implement structured data.
We design a new Exprs-unsafe-data-lang v8 below. The language is large, as we include several new structured data types and their primitives.
| p | ::= | (module b ... e) | ||
| b | ::= | (define label (lambda (aloc ...) e)) | ||
| pred | ::= | e | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (let ([aloc e] ...) pred) | |||
| | | (if pred pred pred) | |||
| e | ::= | v | ||
| | | (primop e ...) | |||
| | | (call e e ...) | |||
| | | (let ([aloc e] ...) e) | |||
| | | (if pred e e) | |||
| | | (begin effect ... e) | |||
| effect | ::= | (primop e ...) | ||
| | | (begin effect ... effect) | |||
| primop | ::= | unsafe-fx* | ||
| | | unsafe-fx+ | |||
| | | unsafe-fx- | |||
| | | eq? | |||
| | | unsafe-fx< | |||
| | | unsafe-fx<= | |||
| | | unsafe-fx> | |||
| | | unsafe-fx>= | |||
| | | fixnum? | |||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not | |||
| | | pair? | |||
| | | vector? | |||
| | | cons | |||
| | | unsafe-car | |||
| | | unsafe-cdr | |||
| | | unsafe-make-vector | |||
| | | unsafe-vector-length | |||
| | | unsafe-vector-set! | |||
| | | unsafe-vector-ref | |||
| primop | ::= | binop | ||
| | | unop | |||
| binop | ::= | unsafe-fx* | ||
| | | unsafe-fx+ | |||
| | | unsafe-fx- | |||
| | | eq? | |||
| | | unsafe-fx< | |||
| | | unsafe-fx<= | |||
| | | unsafe-fx> | |||
| | | unsafe-fx>= | |||
| unop | ::= | fixnum? | ||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not |
| p | ::= | (module b ... e) | ||
| b | ::= | (define label (lambda (aloc ...) e)) | ||
| pred | ::= | e | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (let ([aloc e] ...) pred) | |||
| | | (if pred pred pred) | |||
| e | ::= | v | ||
| | | (primop e ...) | |||
| | | (call e e ...) | |||
| | | (let ([aloc e] ...) e) | |||
| | | (if pred e e) | |||
| | | (begin effect ... e) | |||
| effect | ::= | (primop e ...) | ||
| | | (begin effect ... effect) | |||
| v | ::= | label | ||
| | | aloc | |||
| | | fixnum | |||
| | | #t | |||
| | | #f | |||
| | | empty | |||
| | | (void) | |||
| | | (error uint8) | |||
| | | ascii-char-literal | |||
| primop | ::= | unsafe-fx* | ||
| | | unsafe-fx+ | |||
| | | unsafe-fx- | |||
| | | eq? | |||
| | | unsafe-fx< | |||
| | | unsafe-fx<= | |||
| | | unsafe-fx> | |||
| | | unsafe-fx>= | |||
| | | fixnum? | |||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not | |||
| | | pair? | |||
| | | vector? | |||
| | | cons | |||
| | | unsafe-car | |||
| | | unsafe-cdr | |||
| | | unsafe-make-vector | |||
| | | unsafe-vector-length | |||
| | | unsafe-vector-set! | |||
| | | unsafe-vector-ref | |||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| fixnum | ::= | int61? | ||
| uint8 | ::= | uint8? | ||
| ascii-char-literal | ::= | ascii-char-literal? |
We add new primops for each of our new data types. Since the number of primitive operations is growing, we simplify the syntax to only give primops, rather than distinguishing unops, binops, and so on, so we can easily group like primops with like.
We also add impure computations, since vectors are a mutable data structure. Only effectful primops, those ending with !, are allowed in effect context.
Pairs are constructed using (cons e_1 e_2). The predicate pair? should return #t when passed any value constructed this way, and #f for any other value—
(eq? (pair? (cons e_1 e_2)) #t). (unsafe-car e) returns the value of the first element of the pair, and (unsafe-cdr e) returns the value of the second element. That is, (eq? (unsafe-car (cons e_1 e_2)) e_1) and (eq? (unsafe-cdr (cons e_1 e_2)) e_2). Vectors are essentially arrays that know their length. They are constructed using (unsafe-make-vector e); the constructor takes the length of the vector as the argument. The predicate vector? should return #t for any value constructed this way, and #f for any other value—
(eq? (vector? (unsafe-make-vector e)) #t). (unsafe-vector-ref e_1 e_2) returns the value at index e_2 in the vector e_1. (unsafe-vector-set! e_1 e_2 e_3) mutates the index e_2 in the vector e_1, setting its value to the value of e_3. (unsafe-vector-set! e_1 e_2 e_3) is only allowed in impure computation context.
We follow the same pattern as Data types: Immediates to implement the new predicates.
To implement constructors, we need to compile to alloc. cons allocates two words of space, storing its first argument in the first word and the second element in the second word, producing `(alloc ,(current-pair-size)). The ptr we get back needs to be tagged, so we produce `(bitwise-ior (alloc ,(current-pair-size)) ,(current-pair-tag)). unsafe-make-vector allocates one word for the length, and then one word for every element of the vector. That is, it should allocate n+1 words for a vector of length n.
`(let ([x.1 (bitwise-ior (alloc 16) ,(current-pair-tag))]) (begin (mset! (bitwise-xor x.1 ,(current-pair-tag)) 0 ,e_1) (mset! (bitwise-xor x.1 ,(current-pair-tag)) 8 ,e_2) x.1))
Since the length of the vector is dynamically determined, we do not initialize each field when implementing its constructor. Instead, we expose an unsafe constructor for vectors, and leave it to a safer language to initialize the vector.
`(let ([x.1 (+ (alloc 16) 1)]) (begin (mset! x.1 -1 ,e_1) (mset! x.1 7 ,e_2) x.1))
procedure
p : exprs-unsafe-data-lang-v8?
5.10.2.7 New Safe Primops
All the accessors for the new data types can result in undefined behaviour if used on the wrong ptr. Similarly, vector reference can access undefined values if the vector is constructed but never initialized.
Below we define Exprs-unique-lang v8.
| p | ::= | (module b ... e) | ||
| b | ::= | (define label (lambda (aloc ...) e)) | ||
| e | ::= | v | ||
| | | (call e e ...) | |||
| | | (let ([aloc e] ...) e) | |||
| | | (if e e e) | |||
| v | ::= | label | ||
| | | aloc | |||
| | | prim-f | |||
| | | fixnum | |||
| | | #t | |||
| | | #f | |||
| | | empty | |||
| | | (void) | |||
| | | (error uint8) | |||
| | | ascii-char-literal | |||
| prim-f | ::= | * | ||
| | | + | |||
| | | - | |||
| | | < | |||
| | | <= | |||
| | | > | |||
| | | >= | |||
| | | eq? | |||
| | | fixnum? | |||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not | |||
| | | pair? | |||
| | | vector? | |||
| | | cons | |||
| | | car | |||
| | | cdr | |||
| | | make-vector | |||
| | | vector-length | |||
| | | vector-set! | |||
| | | vector-ref | |||
| prim-f | ::= | binop | ||
| | | unop | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | < | |||
| | | eq? | |||
| | | <= | |||
| | | > | |||
| | | >= | |||
| unop | ::= | fixnum? | ||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not |
| p | ::= | (module b ... e) | ||
| b | ::= | (define label (lambda (aloc ...) e)) | ||
| e | ::= | v | ||
| | | (call e e ...) | |||
| | | (let ([aloc e] ...) e) | |||
| | | (if e e e) | |||
| v | ::= | label | ||
| | | aloc | |||
| | | prim-f | |||
| | | fixnum | |||
| | | #t | |||
| | | #f | |||
| | | empty | |||
| | | (void) | |||
| | | (error uint8) | |||
| | | ascii-char-literal | |||
| prim-f | ::= | * | ||
| | | + | |||
| | | - | |||
| | | < | |||
| | | <= | |||
| | | > | |||
| | | >= | |||
| | | eq? | |||
| | | fixnum? | |||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not | |||
| | | pair? | |||
| | | vector? | |||
| | | cons | |||
| | | car | |||
| | | cdr | |||
| | | make-vector | |||
| | | vector-length | |||
| | | vector-set! | |||
| | | vector-ref | |||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| fixnum | ::= | int61? | ||
| uint8 | ::= | uint8? | ||
| ascii-char-literal | ::= | ascii-char-literal? |
Note that in this language, we remove begin. The user must manually call impure functions and bind the result. The result of an effectful function could be void, or an error. It would be unwise, although technically safe, to simple discard errors.
To implement this safe language, we wrap all accessors to perform dynamic tag checking before using the unsafe operations. We also wrap unsafe-make-vector to initialize all elements to 0.
; Symbol x Symbol x (List-of Parameter-Types) ; The first symbol is the name of a function in the source language. ; The second is either the name of a primop or a label in the target language implementing the ; behaviour safely, assuming well-typed parameters. ; The third is list of predicates, one for each argument to the source ; function, to check the parameters with. `any?` is specially recognized to ; not be checked. (define prim-f-specs `((* unsafe-fx* (fixnum? fixnum?)) (+ unsafe-fx+ (fixnum? fixnum?)) (- unsafe-fx- (fixnum? fixnum?)) (< unsafe-fx< (fixnum? fixnum?)) (<= unsafe-fx<= (fixnum? fixnum?)) (> unsafe-fx> (fixnum? fixnum?)) (>= unsafe-fx>= (fixnum? fixnum?)) (make-vector ,make-init-vector-label (fixnum?)) (vector-length unsafe-vector-length (vector?)) (vector-set! ,unsafe-vector-set!-label (vector? fixnum? any?)) (vector-ref ,unsafe-vector-ref-label (vector? fixnum?)) (car unsafe-car (pair?)) (cdr unsafe-cdr (pair?)) ,@(map (lambda (x) `(,x ,x (any?))) '(fixnum? boolean? empty? void? ascii-char? error? pair? vector? not)) ,@(map (lambda (x) `(,x ,x (any? any?))) '(cons eq?))))
All impure computations, those that end in !, should only return (void) or an error.
procedure
p : exprs-unique-lang-v8
5.10.2.8 uniquify
Finally, we define the source language. Below we define Exprs-lang v8.
| p | ::= | (module b ... e) | ||
| b | ::= | (define x (lambda (x ...) e)) | ||
| e | ::= | v | ||
| | | (call e e ...) | |||
| | | (let ([x e] ...) e) | |||
| | | (if e e e) | |||
| x | ::= | name? | ||
| | | prim-f | |||
| v | ::= | x | ||
| | | fixnum | |||
| | | #t | |||
| | | #f | |||
| | | empty | |||
| | | (void) | |||
| | | (error uint8) | |||
| | | ascii-char-literal | |||
| prim-f | ::= | * | ||
| | | + | |||
| | | - | |||
| | | < | |||
| | | <= | |||
| | | > | |||
| | | >= | |||
| | | eq? | |||
| | | fixnum? | |||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not | |||
| | | pair? | |||
| | | vector? | |||
| | | cons | |||
| | | car | |||
| | | cdr | |||
| | | make-vector | |||
| | | vector-length | |||
| | | vector-set! | |||
| | | vector-ref | |||
| prim-f | ::= | binop | ||
| | | unop | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | eq? | |||
| | | < | |||
| | | <= | |||
| | | > | |||
| | | >= | |||
| unop | ::= | fixnum? | ||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not | |||
| fixnum | ::= | int61? | ||
| uint8 | ::= | uint8? | ||
| ascii-char-literal | ::= | ascii-char-literal? |
5.10.3 Appendix: Overview
5.10.4 Appendix: Languages
procedure
(exprs-lang-v8? a) → boolean?
a : any/c
exprs-lang-v8 : grammar?
| p | ::= | (module b ... e) | ||
| b | ::= | (define x (lambda (x ...) e)) | ||
| e | ::= | v | ||
| | | (call e e ...) | |||
| | | (let ([x e] ...) e) | |||
| | | (if e e e) | |||
| x | ::= | name? | ||
| | | prim-f | |||
| v | ::= | x | ||
| | | fixnum | |||
| | | #t | |||
| | | #f | |||
| | | empty | |||
| | | (void) | |||
| | | (error uint8) | |||
| | | ascii-char-literal | |||
| prim-f | ::= | * | ||
| | | + | |||
| | | - | |||
| | | < | |||
| | | <= | |||
| | | > | |||
| | | >= | |||
| | | eq? | |||
| | | fixnum? | |||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not | |||
| | | pair? | |||
| | | vector? | |||
| | | cons | |||
| | | car | |||
| | | cdr | |||
| | | make-vector | |||
| | | vector-length | |||
| | | vector-set! | |||
| | | vector-ref | |||
| fixnum | ::= | int61? | ||
| uint8 | ::= | uint8? | ||
| ascii-char-literal | ::= | ascii-char-literal? |
procedure
(exprs-unique-lang-v8? a) → boolean?
a : any/c
exprs-unique-lang-v8 : grammar?
| p | ::= | (module b ... e) | ||
| b | ::= | (define label (lambda (aloc ...) e)) | ||
| e | ::= | v | ||
| | | (call e e ...) | |||
| | | (let ([aloc e] ...) e) | |||
| | | (if e e e) | |||
| v | ::= | label | ||
| | | aloc | |||
| | | prim-f | |||
| | | fixnum | |||
| | | #t | |||
| | | #f | |||
| | | empty | |||
| | | (void) | |||
| | | (error uint8) | |||
| | | ascii-char-literal | |||
| prim-f | ::= | * | ||
| | | + | |||
| | | - | |||
| | | < | |||
| | | <= | |||
| | | > | |||
| | | >= | |||
| | | eq? | |||
| | | fixnum? | |||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not | |||
| | | pair? | |||
| | | vector? | |||
| | | cons | |||
| | | car | |||
| | | cdr | |||
| | | make-vector | |||
| | | vector-length | |||
| | | vector-set! | |||
| | | vector-ref | |||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| fixnum | ::= | int61? | ||
| uint8 | ::= | uint8? | ||
| ascii-char-literal | ::= | ascii-char-literal? |
procedure
(exprs-unsafe-data-lang-v8? a) → boolean?
a : any/c
exprs-unsafe-data-lang-v8 : grammar?
| p | ::= | (module b ... e) | ||
| b | ::= | (define label (lambda (aloc ...) e)) | ||
| pred | ::= | e | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (let ([aloc e] ...) pred) | |||
| | | (if pred pred pred) | |||
| e | ::= | v | ||
| | | (primop e ...) | |||
| | | (call e e ...) | |||
| | | (let ([aloc e] ...) e) | |||
| | | (if pred e e) | |||
| | | (begin effect ... e) | |||
| effect | ::= | (primop e ...) | ||
| | | (begin effect ... effect) | |||
| v | ::= | label | ||
| | | aloc | |||
| | | fixnum | |||
| | | #t | |||
| | | #f | |||
| | | empty | |||
| | | (void) | |||
| | | (error uint8) | |||
| | | ascii-char-literal | |||
| primop | ::= | unsafe-fx* | ||
| | | unsafe-fx+ | |||
| | | unsafe-fx- | |||
| | | eq? | |||
| | | unsafe-fx< | |||
| | | unsafe-fx<= | |||
| | | unsafe-fx> | |||
| | | unsafe-fx>= | |||
| | | fixnum? | |||
| | | boolean? | |||
| | | empty? | |||
| | | void? | |||
| | | ascii-char? | |||
| | | error? | |||
| | | not | |||
| | | pair? | |||
| | | vector? | |||
| | | cons | |||
| | | unsafe-car | |||
| | | unsafe-cdr | |||
| | | unsafe-make-vector | |||
| | | unsafe-vector-length | |||
| | | unsafe-vector-set! | |||
| | | unsafe-vector-ref | |||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| fixnum | ::= | int61? | ||
| uint8 | ::= | uint8? | ||
| ascii-char-literal | ::= | ascii-char-literal? |
procedure
(exprs-bits-lang-v8/contexts? a) → boolean?
a : any/c
exprs-bits-lang-v8/contexts : grammar?
| p | ::= | (module b ... tail) | ||
| b | ::= | (define label (lambda (aloc ...) tail)) | ||
| pred | ::= | (relop value value) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (let ([aloc value] ...) pred) | |||
| | | (if pred pred pred) | |||
| | | (begin effect ... pred) | |||
| tail | ::= | value | ||
| | | (let ([aloc value] ...) tail) | |||
| | | (if pred tail tail) | |||
| | | (begin effect ... tail) | |||
| value | ::= | triv | ||
| | | (binop value value) | |||
| | | (mref value value) | |||
| | | (alloc value) | |||
| | | (call value value ...) | |||
| | | (let ([aloc value]) value) | |||
| | | (if pred value value) | |||
| | | (begin effect ... value) | |||
| effect | ::= | (mset! value value value) | ||
| | | (begin effect ... effect) | |||
| triv | ::= | label | ||
| | | aloc | |||
| | | int64 | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? |
procedure
(values-bits-lang-v8? a) → boolean?
a : any/c
values-bits-lang-v8 : grammar?
| p | ::= | (module (define label (lambda (aloc ...) tail)) ... tail) | ||
| pred | ::= | (relop opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (let ([aloc value] ...) pred) | |||
| | | (if pred pred pred) | |||
| | | (begin effect ... pred) | |||
| tail | ::= | value | ||
| | | (let ([aloc value] ...) tail) | |||
| | | (if pred tail tail) | |||
| | | (call triv opand ...) | |||
| | | (begin effect ... tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref aloc opand) | |||
| | | (alloc opand) | |||
| | | (let ([aloc value] ...) value) | |||
| | | (if pred value value) | |||
| | | (call triv opand ...) | |||
| | | (begin effect ... value) | |||
| effect | ::= | (mset! aloc opand value) | ||
| | | (let ([aloc value] ...) effect) | |||
| | | (begin effect ... effect) | |||
| opand | ::= | int64 | ||
| | | aloc | |||
| triv | ::= | opand | ||
| | | label | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? |
procedure
(proc-imp-mf-lang-v8? a) → boolean?
a : any/c
proc-imp-mf-lang-v8 : grammar?
| p | ::= |
| ||||
| entry | ::= | tail | ||||
| pred | ::= | (relop opand opand) | ||||
| | | (true) | |||||
| | | (false) | |||||
| | | (not pred) | |||||
| | | (begin effect ... pred) | |||||
| | | (if pred pred pred) | |||||
| tail | ::= | value | ||||
| | | (call triv opand ...) | |||||
| | | (begin effect ... tail) | |||||
| | | (if pred tail tail) | |||||
| value | ::= | triv | ||||
| | | (binop opand opand) | |||||
| | | (mref aloc opand) | |||||
| | | (alloc opand) | |||||
| | | (begin effect ... value) | |||||
| | | (if pred value value) | |||||
| | | (call triv opand ...) | |||||
| effect | ::= | (set! aloc value) | ||||
| | | (mset! aloc opand value) | |||||
| | | (begin effect ... effect) | |||||
| | | (if pred effect effect) | |||||
| opand | ::= | int64 | ||||
| | | aloc | |||||
| triv | ::= | opand | ||||
| | | label | |||||
| binop | ::= | * | ||||
| | | + | |||||
| | | - | |||||
| | | bitwise-and | |||||
| | | bitwise-ior | |||||
| | | bitwise-xor | |||||
| | | arithmetic-shift-right | |||||
| relop | ::= | < | ||||
| | | <= | |||||
| | | = | |||||
| | | >= | |||||
| | | > | |||||
| | | != | |||||
| int64 | ::= | int64? | ||||
| aloc | ::= | aloc? | ||||
| label | ::= | label? |
procedure
(imp-mf-lang-v8? a) → boolean?
a : any/c
imp-mf-lang-v8 : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref loc opand) | |||
| | | (alloc opand) | |||
| | | (begin effect ... value) | |||
| | | (if pred value value) | |||
| | | (return-point label tail) | |||
| effect | ::= | (set! loc value) | ||
| | | (mset! loc opand value) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(imp-cmf-lang-v8? a) → boolean?
a : any/c
imp-cmf-lang-v8 : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop opand opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| value | ::= | triv | ||
| | | (binop opand opand) | |||
| | | (mref loc opand) | |||
| | | (alloc opand) | |||
| effect | ::= | (set! loc value) | ||
| | | (mset! loc opand triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(asm-alloc-lang-v8? a) → boolean?
a : any/c
asm-alloc-lang-v8 : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (set! loc (alloc index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(asm-pred-lang-v8? a) → boolean?
a : any/c
asm-pred-lang-v8 : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(asm-pred-lang-v8/locals? a) → boolean?
a : any/c
asm-pred-lang-v8/locals : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)) (locals (aloc ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (begin effect ... effect) | |||
| | | (mset! loc index triv) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(asm-pred-lang-v8/undead? a) → boolean?
a : any/c
asm-pred-lang-v8/undead : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)) (locals (aloc ...)) (call-undead (loc ...)) (undead-out undead-set-tree/rloc?))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(asm-pred-lang-v8/conflicts? a) → boolean?
a : any/c
asm-pred-lang-v8/conflicts : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)) (locals (aloc ...)) (call-undead (loc ...)) (undead-out undead-set-tree/rloc?) (conflicts ((loc (loc ...)) ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(asm-pred-lang-v8/pre-framed? a) → boolean?
a : any/c
asm-pred-lang-v8/pre-framed : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (new-frames (frame ...)) (locals (aloc ...)) (call-undead (loc ...)) (undead-out undead-set-tree/rloc?) (conflicts ((loc (loc ...)) ...)) (assignment ((aloc loc) ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(asm-pred-lang-v8/framed? a) → boolean?
a : any/c
asm-pred-lang-v8/framed : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (locals (aloc ...)) (undead-out undead-set-tree/rloc?) (conflicts ((loc (loc ...)) ...)) (assignment ((aloc loc) ...)))) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(asm-pred-lang-v8/spilled? a) → boolean?
a : any/c
asm-pred-lang-v8/spilled : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (locals (aloc ...)) (undead-out undead-set-tree/rloc?) (conflicts ((loc (loc ...)) ...)) (assignment ((aloc loc) ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(asm-pred-lang-v8/assignments? a) → boolean?
a : any/c
asm-pred-lang-v8/assignments : grammar?
| p | ::= | (module info (define label info tail) ... tail) | ||
| info | ::= | (#:from-contract (info/c (assignment ((aloc loc) ...)))) | ||
| frame | ::= | (aloc ...) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg loc ...) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| opand | ::= | int64 | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| loc | ::= | rloc | ||
| | | aloc | |||
| trg | ::= | label | ||
| | | loc | |||
| index | ::= | int64 | ||
| | | loc | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| label | ::= | label? | ||
| rloc | ::= | register? | ||
| | | fvar? |
procedure
(nested-asm-lang-fvars-v8? a) → boolean?
a : any/c
nested-asm-lang-fvars-v8 : grammar?
| p | ::= | (module (define label tail) ... tail) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| triv | ::= | opand | ||
| | | label | |||
| opand | ::= | int64 | ||
| | | loc | |||
| trg | ::= | label | ||
| | | loc | |||
| loc | ::= | reg | ||
| | | fvar | |||
| index | ::= | int64 | ||
| | | loc | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| aloc | ::= | aloc? | ||
| fvar | ::= | fvar? | ||
| label | ::= | label? |
procedure
(nested-asm-lang-v8? a) → boolean?
a : any/c
nested-asm-lang-v8 : grammar?
| p | ::= | (module (define label tail) ... tail) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| | | (begin effect ... pred) | |||
| | | (if pred pred pred) | |||
| tail | ::= | (jump trg) | ||
| | | (begin effect ... tail) | |||
| | | (if pred tail tail) | |||
| effect | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| | | (begin effect ... effect) | |||
| | | (if pred effect effect) | |||
| | | (return-point label tail) | |||
| triv | ::= | opand | ||
| | | label | |||
| opand | ::= | int64 | ||
| | | loc | |||
| trg | ::= | label | ||
| | | loc | |||
| loc | ::= | reg | ||
| | | addr | |||
| index | ::= | int64 | ||
| | | loc | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| addr | ::= | (fbp - dispoffset) | ||
| fbp | ::= | frame-base-pointer-register? | ||
| dispoffset | ::= | dispoffset? | ||
| label | ::= | label? |
procedure
(block-pred-lang-v8? a) → boolean?
a : any/c
block-pred-lang-v8 : grammar?
| p | ::= | (module b ... b) | ||
| b | ::= | (define label tail) | ||
| pred | ::= | (relop loc opand) | ||
| | | (true) | |||
| | | (false) | |||
| | | (not pred) | |||
| tail | ::= | (jump trg) | ||
| | | (begin s ... tail) | |||
| | | (if pred (jump trg) (jump trg)) | |||
| s | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| triv | ::= | opand | ||
| | | label | |||
| opand | ::= | int64 | ||
| | | loc | |||
| trg | ::= | label | ||
| | | loc | |||
| loc | ::= | reg | ||
| | | addr | |||
| index | ::= | int64 | ||
| | | loc | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| addr | ::= | (fbp - dispoffset) | ||
| fbp | ::= | frame-base-pointer-register? | ||
| dispoffset | ::= | dispoffset? | ||
| label | ::= | label? |
procedure
(block-asm-lang-v8? a) → boolean?
a : any/c
block-asm-lang-v8 : grammar?
| p | ::= | (module b ... b) | ||
| b | ::= | (define label tail) | ||
| tail | ::= | (jump trg) | ||
| | | (begin s ... tail) | |||
| | | (if (relop loc opand) (jump trg) (jump trg)) | |||
| s | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc index triv) | |||
| triv | ::= | opand | ||
| | | label | |||
| opand | ::= | int64 | ||
| | | loc | |||
| trg | ::= | label | ||
| | | loc | |||
| loc | ::= | reg | ||
| | | addr | |||
| index | ::= | int64 | ||
| | | loc | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| addr | ::= | (fbp - dispoffset) | ||
| fbp | ::= | frame-base-pointer-register? | ||
| dispoffset | ::= | dispoffset? | ||
| label | ::= | label? |
procedure
(para-asm-lang-v8? a) → boolean?
a : any/c
para-asm-lang-v8 : grammar?
| p | ::= | (begin s ...) | ||
| s | ::= | (set! loc triv) | ||
| | | (set! loc_1 (binop loc_1 opand)) | |||
| | | (set! loc_1 (mref loc_2 index)) | |||
| | | (mset! loc_1 index triv) | |||
| | | (with-label label s) | |||
| | | (jump trg) | |||
| | | (compare loc opand) | |||
| | | (jump-if relop trg) | |||
| trg | ::= | label | ||
| | | loc | |||
| triv | ::= | opand | ||
| | | label | |||
| opand | ::= | int64 | ||
| | | loc | |||
| loc | ::= | reg | ||
| | | addr | |||
| index | ::= | int64 | ||
| | | loc | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| addr | ::= | (fbp - dispoffset) | ||
| fbp | ::= | frame-base-pointer-register? | ||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| label | ::= | label? | ||
| dispoffset | ::= | dispoffset? |
procedure
(paren-x64-mops-v8? a) → boolean?
a : any/c
paren-x64-mops-v8 : grammar?
| p | ::= | (begin s ...) | ||
| s | ::= | (set! addr int32) | ||
| | | (set! addr trg) | |||
| | | (set! reg loc) | |||
| | | (set! reg triv) | |||
| | | (set! reg_1 (binop reg_1 int32)) | |||
| | | (set! reg_1 (binop reg_1 loc)) | |||
| | | (set! reg_1 (mref reg_2 index)) | |||
| | | (mset! reg_1 index triv) | |||
| | | (with-label label s) | |||
| | | (jump trg) | |||
| | | (compare reg opand) | |||
| | | (jump-if relop label) | |||
| trg | ::= | reg | ||
| | | label | |||
| triv | ::= | trg | ||
| | | int64 | |||
| opand | ::= | int64 | ||
| | | reg | |||
| loc | ::= | reg | ||
| | | addr | |||
| index | ::= | int32 | ||
| | | reg | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r10 | |||
| | | r11 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| addr | ::= | (fbp - dispoffset) | ||
| fbp | ::= | frame-base-pointer-register? | ||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int64 | ::= | int64? | ||
| int32 | ::= | int32? | ||
| label | ::= | label? | ||
| dispoffset | ::= | dispoffset? |
procedure
(paren-x64-v8? a) → boolean?
a : any/c
paren-x64-v8 : grammar?
| p | ::= | (begin s ...) | ||
| s | ::= | (set! addr int32) | ||
| | | (set! addr trg) | |||
| | | (set! reg loc) | |||
| | | (set! reg triv) | |||
| | | (set! reg_1 (binop reg_1 int32)) | |||
| | | (set! reg_1 (binop reg_1 loc)) | |||
| | | (with-label label? s) | |||
| | | (jump trg) | |||
| | | (compare reg opand) | |||
| | | (jump-if relop label) | |||
| trg | ::= | reg | ||
| | | label | |||
| triv | ::= | trg | ||
| | | int64 | |||
| opand | ::= | int64 | ||
| | | reg | |||
| loc | ::= | reg | ||
| | | addr | |||
| reg | ::= | rsp | ||
| | | rbp | |||
| | | rax | |||
| | | rbx | |||
| | | rcx | |||
| | | rdx | |||
| | | rsi | |||
| | | rdi | |||
| | | r8 | |||
| | | r9 | |||
| | | r10 | |||
| | | r11 | |||
| | | r12 | |||
| | | r13 | |||
| | | r14 | |||
| | | r15 | |||
| addr | ::= | (fbp - dispoffset) | ||
| | | (reg + int32) | |||
| | | (reg + reg) | |||
| fbp | ::= | frame-base-pointer-register? | ||
| binop | ::= | * | ||
| | | + | |||
| | | - | |||
| | | bitwise-and | |||
| | | bitwise-ior | |||
| | | bitwise-xor | |||
| | | arithmetic-shift-right | |||
| relop | ::= | < | ||
| | | <= | |||
| | | = | |||
| | | >= | |||
| | | > | |||
| | | != | |||
| int32 | ::= | int32? | ||
| int64 | ::= | int64? | ||
| label | ::= | label? | ||
| dispoffset | ::= | dispoffset? |