compiler/
kernel/
lib/
examples/
std/
arch/
char/
collections/
lang/
alloc/
ast/
gen/
il/
binary/
instructions.rad
14.7 KiB
records.rad
8.3 KiB
structure.rad
7.6 KiB
tests.rad
2.8 KiB
images/
binary.rad
13.9 KiB
images.rad
10.6 KiB
printer.rad
14.7 KiB
module/
parser/
resolver/
scanner/
alloc.rad
4.3 KiB
ast.rad
23.3 KiB
gen.rad
513 B
il.rad
16.1 KiB
lower.rad
272.5 KiB
module.rad
13.2 KiB
package.rad
1.3 KiB
parser.rad
77.8 KiB
resolver.rad
308.6 KiB
scanner.rad
17.5 KiB
sexpr.rad
6.3 KiB
strings.rad
2.2 KiB
types.rad
286 B
sys/
arch.rad
68 B
char.rad
855 B
collections.rad
39 B
fmt.rad
8.1 KiB
intrinsics.rad
467 B
io.rad
1.3 KiB
lang.rad
276 B
mem.rad
2.2 KiB
sys.rad
179 B
testing.rad
2.4 KiB
tests.rad
15.2 KiB
vec.rad
3.2 KiB
std.rad
281 B
scripts/
seed/
sublime/
test/
vim/
.gitignore
351 B
.gitsigners
112 B
CONTRIBUTING
2.1 KiB
LICENSE
1.1 KiB
Makefile
3.8 KiB
README
2.5 KiB
STYLE
2.5 KiB
std.lib
1.4 KiB
std.lib.test
380 B
lib/std/lang/il/binary/records.rad
raw
| 1 | //! Binary data, function and block records built directly from shared RIL. |
| 2 | //! |
| 3 | //! Data: symbol:u32, size:u32, alignment:u32, flags:u8 (readonly bit 0, |
| 4 | //! zero-init bit 1), values:list. Each value is count:u32 then item tag:u8: |
| 5 | //! Val=0 (type:u8, bits:u64), Sym=1 (symbol:u32), Fn=2 (symbol:u32), |
| 6 | //! Str=3 (bytes:string), Undef=4 (one zero/padding byte per repetition). |
| 7 | //! Function: symbol:u32, return type:u8, extern:bool, params:list, blocks:list. |
| 8 | //! Parameter: register:u32, type:u8. Block: label:string, loopDepth:u32, |
| 9 | //! params:list, instructions:list. Debug locations are deliberately omitted. |
| 10 | |
| 11 | use std::lang::il; |
| 12 | use super::instructions; |
| 13 | use super::structure; |
| 14 | |
| 15 | /// Serialize typed parameters with their original register identifiers. |
| 16 | fn putParams(w: *mut super::Writer, params: *[il::Param]) throws (super::Error) { |
| 17 | try super::put32(w, params.len); |
| 18 | for param in params { |
| 19 | try super::put32(w, param.value.n); |
| 20 | try instructions::putType(w, param.type); |
| 21 | } |
| 22 | } |
| 23 | |
| 24 | /// Decode parameters into caller-owned storage. |
| 25 | fn getParams(r: *mut super::Reader) -> *[il::Param] throws (super::Error) { |
| 26 | let count = try super::count(r, 5); |
| 27 | let params = try super::storage(r.arena, @sizeOf(il::Param), @alignOf(il::Param), count, r.offset) as *mut [il::Param]; |
| 28 | for i in 0..count { |
| 29 | let value = try instructions::getReg(r); |
| 30 | let typ = try instructions::getType(r); |
| 31 | set params[i] = il::Param { value, type: typ }; |
| 32 | } |
| 33 | return params; |
| 34 | } |
| 35 | |
| 36 | /// Serialize one data declaration including zero repetition counts and flags. |
| 37 | export fn putData(w: *mut super::Writer, data: *il::Data) throws (super::Error) { |
| 38 | try checkData(data, w.offset); |
| 39 | try super::putSymbol(w, data.name, 1); |
| 40 | try super::put32(w, data.size); |
| 41 | try super::put32(w, data.alignment); |
| 42 | let mut flags: u8 = 0; |
| 43 | if data.readOnly { set flags |= 1; } |
| 44 | if data.isZeroInit { set flags |= 2; } |
| 45 | try super::put8(w, flags); |
| 46 | try super::put32(w, data.values.len); |
| 47 | for value in data.values { |
| 48 | try super::put32(w, value.count); |
| 49 | match value.item { |
| 50 | case il::DataItem::Val { typ, val } => { |
| 51 | try super::put8(w, 0); try instructions::putType(w, typ); try super::put64(w, val as u64); |
| 52 | } |
| 53 | case il::DataItem::Sym(name) => { try super::put8(w, 1); try super::putSymbol(w, name, 1); } |
| 54 | case il::DataItem::Fn(name) => { try super::put8(w, 2); try super::putSymbol(w, name, 2); } |
| 55 | case il::DataItem::Str(bytes) => { try super::put8(w, 3); try super::putString(w, bytes); } |
| 56 | case il::DataItem::Undef => try super::put8(w, 4), |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | /// Decode one initializer item with its exact explicit discriminant. |
| 62 | fn getItem(r: *mut super::Reader) -> il::DataItem throws (super::Error) { |
| 63 | let offset = r.offset; |
| 64 | match try super::get8(r) { |
| 65 | case 0 => { |
| 66 | let typ = try instructions::getType(r); |
| 67 | let val = (try super::get64(r)) as i64; |
| 68 | return il::DataItem::Val { typ, val }; |
| 69 | } |
| 70 | case 1 => return il::DataItem::Sym(try super::getSymbol(r, 1)), |
| 71 | case 2 => return il::DataItem::Fn(try super::getSymbol(r, 2)), |
| 72 | case 3 => return il::DataItem::Str(try super::getString(r)), |
| 73 | case 4 => return il::DataItem::Undef, |
| 74 | else => throw super::error(offset, "invalid RIL data item tag"), |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | /// Decode and structurally validate a data record before native emission. |
| 79 | export fn getData(r: *mut super::Reader) -> il::Data throws (super::Error) { |
| 80 | let offset = r.offset; |
| 81 | let name = try super::declaration(r, 1); |
| 82 | let size = try super::get32(r); |
| 83 | let alignment = try instructions::getAlignment(r); |
| 84 | let flagOffset = r.offset; |
| 85 | let flags = try super::get8(r); |
| 86 | if flags > 3 { throw super::error(flagOffset, "unknown RIL data flags"); } |
| 87 | let count = try super::count(r, 5); |
| 88 | let values = try super::storage(r.arena, @sizeOf(il::DataValue), @alignOf(il::DataValue), count, r.offset) as *mut [il::DataValue]; |
| 89 | for i in 0..count { |
| 90 | let repeat = try super::get32(r); |
| 91 | let item = try getItem(r); |
| 92 | set values[i] = il::DataValue { item, count: repeat }; |
| 93 | } |
| 94 | let data = il::Data { name, size, alignment, readOnly: (flags & 1) <> 0, isZeroInit: (flags & 2) <> 0, values }; |
| 95 | try checkData(&data, offset); |
| 96 | return data; |
| 97 | } |
| 98 | |
| 99 | /// Bound initializer byte arithmetic against the declared extent. A zero-init |
| 100 | /// flag may not discard nonzero bytes or relocations during image placement. |
| 101 | fn checkData(data: *il::Data, offset: u32) throws (super::Error) { |
| 102 | if data.alignment == 0 or (data.alignment & (data.alignment - 1)) <> 0 { |
| 103 | throw super::error(offset, "RIL alignment must be a nonzero power of two"); |
| 104 | } |
| 105 | if data.readOnly and data.isZeroInit { |
| 106 | throw super::error(offset, "RIL read-only data requires an initializer"); |
| 107 | } |
| 108 | let mut size: u64 = 0; |
| 109 | for value in data.values { |
| 110 | let mut width: u32 = 0; |
| 111 | let mut zero = true; |
| 112 | match value.item { |
| 113 | case il::DataItem::Val { typ, val } => { |
| 114 | set width = il::typeSize(typ); |
| 115 | // Only the stored low bytes contribute to narrow initializers. |
| 116 | if width == 8 { set zero = val == 0; } |
| 117 | else { set zero = ((val as u64) & ((1 as u64 << (width as u64 * 8)) - 1)) == 0; } |
| 118 | } |
| 119 | case il::DataItem::Sym(_), il::DataItem::Fn(_) => { set width = 8; set zero = false; } |
| 120 | case il::DataItem::Str(bytes) => { |
| 121 | set width = bytes.len; |
| 122 | for byte in bytes { if byte <> 0 { set zero = false; } } |
| 123 | } |
| 124 | case il::DataItem::Undef => set width = 1, |
| 125 | } |
| 126 | let bytes = width as u64 * value.count as u64; |
| 127 | if bytes > data.size as u64 - size { throw super::error(offset, "RIL initializer exceeds data size"); } |
| 128 | set size += bytes; |
| 129 | if data.isZeroInit and value.count <> 0 and not zero { |
| 130 | throw super::error(offset, "RIL zero-init data contains a nonzero initializer"); |
| 131 | } |
| 132 | } |
| 133 | if not data.isZeroInit and size <> data.size as u64 { |
| 134 | throw super::error(offset, "RIL initializer size differs from data size"); |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | /// Serialize all blocks, including unreferenced empty blocks retained by lowering. |
| 139 | export fn putFn(w: *mut super::Writer, func: *il::Fn) throws (super::Error) { |
| 140 | try super::putSymbol(w, func.name, 2); |
| 141 | try instructions::putType(w, func.returnType); |
| 142 | try super::put8(w, 1 if func.isExtern else 0); |
| 143 | try putParams(w, func.params); |
| 144 | try super::put32(w, func.blocks.len); |
| 145 | for block in func.blocks { |
| 146 | try super::putString(w, block.label); |
| 147 | try super::put32(w, block.loopDepth); |
| 148 | try putParams(w, block.params); |
| 149 | try super::put32(w, block.instrs.len); |
| 150 | for instr in block.instrs { try instructions::put(w, instr); } |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | /// Decode a function and reconstruct allocator metadata only after all block |
| 155 | /// indices are available. Temporary locations identify malformed instructions. |
| 156 | export fn getFn(r: *mut super::Reader) -> il::Fn throws (super::Error) { |
| 157 | let offset = r.offset; |
| 158 | let name = try super::declaration(r, 2); |
| 159 | let returnType = try instructions::getType(r); |
| 160 | let isExtern = try super::getBool(r); |
| 161 | let params = try getParams(r); |
| 162 | let count = try super::count(r, 16); |
| 163 | let blocks = try super::storage(r.arena, @sizeOf(il::Block), @alignOf(il::Block), count, r.offset) as *mut [il::Block]; |
| 164 | for i in 0..count { |
| 165 | let labelOffset = r.offset; |
| 166 | let bytes = try super::getString(r); |
| 167 | let label = try super::intern(r, bytes, labelOffset); |
| 168 | let loopDepth = try super::get32(r); |
| 169 | let blockParams = try getParams(r); |
| 170 | let instrCount = try super::count(r, 1); |
| 171 | let instrs = try super::storage(r.arena, @sizeOf(il::Instr), @alignOf(il::Instr), instrCount, r.offset) as *mut [il::Instr]; |
| 172 | let locs = try super::storage(r.arena, @sizeOf(il::SrcLoc), @alignOf(il::SrcLoc), instrCount, r.offset) as *mut [il::SrcLoc]; |
| 173 | for j in 0..instrCount { |
| 174 | set locs[j] = il::SrcLoc { moduleId: 0, offset: r.offset }; |
| 175 | set instrs[j] = try instructions::get(r); |
| 176 | } |
| 177 | set blocks[i] = il::Block { label, params: blockParams, instrs, locs, preds: &[], loopDepth }; |
| 178 | } |
| 179 | let mut func = il::Fn { name, params, returnType, isExtern, isLeaf: true, blocks }; |
| 180 | try structure::reconstruct(r, &mut func, blocks, offset); |
| 181 | return func; |
| 182 | } |