1// Copyright 2017 The Wuffs Authors. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// Package builtin lists Wuffs' built-in concepts such as status codes. 16package builtin 17 18import ( 19 t "github.com/google/wuffs/lang/token" 20) 21 22var FourCCs = [...][2]string{ 23 {"ICCP", "International Color Consortium Profile"}, 24 {"XMP ", "Extensible Metadata Platform"}, 25} 26 27var Statuses = [...]string{ 28 // Warnings. 29 `"@end of data"`, 30 `"@metadata reported"`, 31 32 // Suspensions. 33 `"$short read"`, 34 `"$short write"`, 35 36 // Errors. 37 `"#bad I/O position"`, 38 `"#bad argument (length too short)"`, 39 `"#bad argument"`, 40 `"#bad call sequence"`, 41 `"#bad receiver"`, 42 `"#bad restart"`, 43 `"#bad sizeof receiver"`, 44 `"#bad workbuf length"`, 45 `"#bad wuffs version"`, 46 `"#cannot return a suspension"`, 47 `"#disabled by previous error"`, 48 `"#initialize falsely claimed already zeroed"`, 49 `"#initialize not called"`, 50 `"#interleaved coroutine calls"`, 51 `"#not enough data"`, 52 `"#unsupported option"`, 53 `"#too much data"`, 54} 55 56// TODO: a collection of forbidden variable names like and, or, not, as, ref, 57// deref, false, true, in, out, this, u8, u16, etc? 58 59var Types = []string{ 60 // TODO: i8, i16, i32, i64. 61 "u8", 62 "u16", 63 "u32", 64 "u64", 65 66 "empty_struct", 67 "bool", 68 "utility", 69 70 "range_ii_u32", 71 "range_ie_u32", 72 "range_ii_u64", 73 "range_ie_u64", 74 "rect_ie_u32", 75 "rect_ii_u32", 76 77 "io_reader", 78 "io_writer", 79 "status", 80 81 "frame_config", 82 "image_config", 83 "pixel_buffer", 84 "pixel_config", 85 "pixel_swizzler", 86 87 "decode_frame_options", 88} 89 90var Funcs = []string{ 91 "u8.high_bits(n u32[..8]) u8", 92 "u8.low_bits(n u32[..8]) u8", 93 "u8.max(x u8) u8", 94 "u8.min(x u8) u8", 95 96 "u16.high_bits(n u32[..16]) u16", 97 "u16.low_bits(n u32[..16]) u16", 98 "u16.max(x u16) u16", 99 "u16.min(x u16) u16", 100 101 "u32.high_bits(n u32[..32]) u32", 102 "u32.low_bits(n u32[..32]) u32", 103 "u32.max(x u32) u32", 104 "u32.min(x u32) u32", 105 106 "u64.high_bits(n u32[..64]) u64", 107 "u64.low_bits(n u32[..64]) u64", 108 "u64.max(x u64) u64", 109 "u64.min(x u64) u64", 110 111 // ---- utility 112 113 "utility.make_range_ii_u32(min_incl u32, max_incl u32) range_ii_u32", 114 "utility.make_range_ie_u32(min_incl u32, max_excl u32) range_ie_u32", 115 "utility.make_range_ii_u64(min_incl u64, max_incl u64) range_ii_u64", 116 "utility.make_range_ie_u64(min_incl u64, max_excl u64) range_ie_u64", 117 "utility.make_rect_ii_u32(min_incl_x u32, min_incl_y u32, max_incl_x u32, max_incl_y u32) rect_ii_u32", 118 "utility.make_rect_ie_u32(min_incl_x u32, min_incl_y u32, max_excl_x u32, max_excl_y u32) rect_ie_u32", 119 "utility.null_io_reader() io_reader", 120 "utility.null_io_writer() io_writer", 121 "utility.null_slice_u8() slice u8", 122 123 // ---- ranges 124 125 "range_ie_u32.reset!()", 126 "range_ie_u32.get_min_incl() u32", 127 "range_ie_u32.get_max_excl() u32", 128 "range_ie_u32.intersect(r range_ie_u32) range_ie_u32", 129 "range_ie_u32.unite(r range_ie_u32) range_ie_u32", 130 131 "range_ii_u32.reset!()", 132 "range_ii_u32.get_min_incl() u32", 133 "range_ii_u32.get_max_incl() u32", 134 "range_ii_u32.intersect(r range_ii_u32) range_ii_u32", 135 "range_ii_u32.unite(r range_ii_u32) range_ii_u32", 136 137 "range_ie_u64.reset!()", 138 "range_ie_u64.get_min_incl() u64", 139 "range_ie_u64.get_max_excl() u64", 140 "range_ie_u64.intersect(r range_ie_u64) range_ie_u64", 141 "range_ie_u64.unite(r range_ie_u64) range_ie_u64", 142 143 "range_ii_u64.reset!()", 144 "range_ii_u64.get_min_incl() u64", 145 "range_ii_u64.get_max_incl() u64", 146 "range_ii_u64.intersect(r range_ii_u64) range_ii_u64", 147 "range_ii_u64.unite(r range_ii_u64) range_ii_u64", 148 149 // ---- io_reader 150 151 "io_reader.can_undo_byte() bool", 152 "io_reader.undo_byte!()", 153 154 "io_reader.read_u8?() u8", 155 156 "io_reader.read_u16be?() u16", 157 "io_reader.read_u16le?() u16", 158 159 "io_reader.read_u8_as_u32?() u32[..0xFF]", 160 "io_reader.read_u16be_as_u32?() u32[..0xFFFF]", 161 "io_reader.read_u16le_as_u32?() u32[..0xFFFF]", 162 "io_reader.read_u24be_as_u32?() u32[..0xFFFFFF]", 163 "io_reader.read_u24le_as_u32?() u32[..0xFFFFFF]", 164 "io_reader.read_u32be?() u32", 165 "io_reader.read_u32le?() u32", 166 167 "io_reader.read_u8_as_u64?() u64[..0xFF]", 168 "io_reader.read_u16be_as_u64?() u64[..0xFFFF]", 169 "io_reader.read_u16le_as_u64?() u64[..0xFFFF]", 170 "io_reader.read_u24be_as_u64?() u64[..0xFFFFFF]", 171 "io_reader.read_u24le_as_u64?() u64[..0xFFFFFF]", 172 "io_reader.read_u32be_as_u64?() u64[..0xFFFFFFFF]", 173 "io_reader.read_u32le_as_u64?() u64[..0xFFFFFFFF]", 174 "io_reader.read_u40be_as_u64?() u64[..0xFFFFFFFFFF]", 175 "io_reader.read_u40le_as_u64?() u64[..0xFFFFFFFFFF]", 176 "io_reader.read_u48be_as_u64?() u64[..0xFFFFFFFFFFFF]", 177 "io_reader.read_u48le_as_u64?() u64[..0xFFFFFFFFFFFF]", 178 "io_reader.read_u56be_as_u64?() u64[..0xFFFFFFFFFFFFFF]", 179 "io_reader.read_u56le_as_u64?() u64[..0xFFFFFFFFFFFFFF]", 180 "io_reader.read_u64be?() u64", 181 "io_reader.read_u64le?() u64", 182 183 // TODO: these should have an explicit pre-condition "available() >= N". 184 // For now, that's implicitly checked (i.e. hard coded). 185 // 186 // The io_reader has peek_etc methods and skip_fast, not read_etc_fast, 187 // because we sometimes advance the pointer by less than what's read. See 188 // https://fgiesen.wordpress.com/2018/02/20/reading-bits-in-far-too-many-ways-part-2/ 189 190 "io_reader.peek_u8() u8", 191 192 "io_reader.peek_u16be() u16", 193 "io_reader.peek_u16le() u16", 194 195 "io_reader.peek_u8_as_u32() u32[..0xFF]", 196 "io_reader.peek_u16be_as_u32() u32[..0xFFFF]", 197 "io_reader.peek_u16le_as_u32() u32[..0xFFFF]", 198 "io_reader.peek_u24be_as_u32() u32[..0xFFFFFF]", 199 "io_reader.peek_u24le_as_u32() u32[..0xFFFFFF]", 200 "io_reader.peek_u32be() u32", 201 "io_reader.peek_u32le() u32", 202 203 "io_reader.peek_u8_as_u64() u64[..0xFF]", 204 "io_reader.peek_u16be_as_u64() u64[..0xFFFF]", 205 "io_reader.peek_u16le_as_u64() u64[..0xFFFF]", 206 "io_reader.peek_u24be_as_u64() u64[..0xFFFFFF]", 207 "io_reader.peek_u24le_as_u64() u64[..0xFFFFFF]", 208 "io_reader.peek_u32be_as_u64() u64[..0xFFFFFFFF]", 209 "io_reader.peek_u32le_as_u64() u64[..0xFFFFFFFF]", 210 "io_reader.peek_u40be_as_u64() u64[..0xFFFFFFFFFF]", 211 "io_reader.peek_u40le_as_u64() u64[..0xFFFFFFFFFF]", 212 "io_reader.peek_u48be_as_u64() u64[..0xFFFFFFFFFFFF]", 213 "io_reader.peek_u48le_as_u64() u64[..0xFFFFFFFFFFFF]", 214 "io_reader.peek_u56be_as_u64() u64[..0xFFFFFFFFFFFFFF]", 215 "io_reader.peek_u56le_as_u64() u64[..0xFFFFFFFFFFFFFF]", 216 "io_reader.peek_u64be() u64", 217 "io_reader.peek_u64le() u64", 218 219 "io_reader.available() u64", 220 "io_reader.count_since(mark u64) u64", 221 "io_reader.mark() u64", 222 "io_reader.position() u64", 223 "io_reader.since(mark u64) slice u8", 224 "io_reader.take!(n u64) slice u8", 225 226 "io_reader.skip?(n u32)", 227 228 // TODO: this should have explicit pre-conditions "actual <= worst_case" 229 // and "worst_case <= available()". As an implementation restriction, we 230 // also require that worst_case has a constant value. For now, that's all 231 // implicitly checked (i.e. hard coded). 232 "io_reader.skip_fast!(actual u32, worst_case u32)", 233 234 // ---- io_writer 235 236 "io_writer.write_u8?(x u8)", 237 "io_writer.write_u16be?(x u16)", 238 "io_writer.write_u16le?(x u16)", 239 "io_writer.write_u24be?(x u32[..0xFFFFFF])", 240 "io_writer.write_u24le?(x u32[..0xFFFFFF])", 241 "io_writer.write_u32be?(x u32)", 242 "io_writer.write_u32le?(x u32)", 243 "io_writer.write_u40be?(x u64[..0xFFFFFFFFFF])", 244 "io_writer.write_u40le?(x u64[..0xFFFFFFFFFF])", 245 "io_writer.write_u48be?(x u64[..0xFFFFFFFFFFFF])", 246 "io_writer.write_u48le?(x u64[..0xFFFFFFFFFFFF])", 247 "io_writer.write_u56be?(x u64[..0xFFFFFFFFFFFFFF])", 248 "io_writer.write_u56le?(x u64[..0xFFFFFFFFFFFFFF])", 249 "io_writer.write_u64be?(x u64)", 250 "io_writer.write_u64le?(x u64)", 251 252 // TODO: these should have an explicit pre-condition "available() >= N". 253 // For now, that's implicitly checked (i.e. hard coded). 254 // 255 // The io_writer has write_fast_etc methods, not poke_etc and skip_fast, 256 // because skip_fast could leave uninitialized bytes in the io_buffer. 257 "io_writer.write_fast_u8!(x u8)", 258 "io_writer.write_fast_u16be!(x u16)", 259 "io_writer.write_fast_u16le!(x u16)", 260 "io_writer.write_fast_u24be!(x u32[..0xFFFFFF])", 261 "io_writer.write_fast_u24le!(x u32[..0xFFFFFF])", 262 "io_writer.write_fast_u32be!(x u32)", 263 "io_writer.write_fast_u32le!(x u32)", 264 "io_writer.write_fast_u40be!(x u64[..0xFFFFFFFFFF])", 265 "io_writer.write_fast_u40le!(x u64[..0xFFFFFFFFFF])", 266 "io_writer.write_fast_u48be!(x u64[..0xFFFFFFFFFFFF])", 267 "io_writer.write_fast_u48le!(x u64[..0xFFFFFFFFFFFF])", 268 "io_writer.write_fast_u56be!(x u64[..0xFFFFFFFFFFFFFF])", 269 "io_writer.write_fast_u56le!(x u64[..0xFFFFFFFFFFFFFF])", 270 "io_writer.write_fast_u64be!(x u64)", 271 "io_writer.write_fast_u64le!(x u64)", 272 273 "io_writer.available() u64", 274 "io_writer.count_since(mark u64) u64", 275 "io_writer.history_available() u64", 276 "io_writer.mark() u64", 277 "io_writer.position() u64", 278 "io_writer.since(mark u64) slice u8", 279 280 "io_writer.copy_from_slice!(s slice u8) u64", 281 "io_writer.copy_n_from_history!(n u32, distance u32) u32", 282 "io_writer.copy_n_from_reader!(n u32, r io_reader) u32", 283 "io_writer.copy_n_from_slice!(n u32, s slice u8) u32", 284 285 // TODO: this should have explicit pre-conditions: 286 // - n <= this.available() 287 // - distance > 0 288 // - distance <= this.since_mark().length() 289 // For now, that's all implicitly checked (i.e. hard coded). 290 "io_writer.copy_n_from_history_fast!(n u32, distance u32) u32", 291 292 // ---- status 293 294 // TODO: should we add is_complete? 295 "status.is_error() bool", 296 "status.is_ok() bool", 297 "status.is_suspension() bool", 298 "status.is_warning() bool", 299 300 // ---- frame_config 301 // Duration's upper bound is the maximum possible i64 value. 302 303 "frame_config.blend() u8", 304 "frame_config.disposal() u8", 305 "frame_config.duration() u64[..0x7FFFFFFFFFFFFFFF]", 306 "frame_config.index() u64", 307 "frame_config.io_position() u64", 308 309 "frame_config.update!(bounds rect_ie_u32, duration u64[..0x7FFFFFFFFFFFFFFF], " + 310 "index u64, io_position u64, blend u8, disposal u8, background_color u32)", 311 312 // ---- image_config 313 314 "image_config.set!(pixfmt u32, pixsub u32, width u32, height u32, " + 315 "first_frame_io_position u64, first_frame_is_opaque bool)", 316 317 // ---- pixel_buffer 318 319 "pixel_buffer.palette() slice u8", 320 "pixel_buffer.pixel_format() u32", 321 "pixel_buffer.plane(p u32[..3]) table u8", 322 323 // ---- pixel_swizzler 324 325 "pixel_swizzler.prepare!(dst_pixfmt u32, dst_palette slice u8, src_pixfmt u32, src_palette slice u8) status", 326 "pixel_swizzler.swizzle_interleaved!(dst slice u8, dst_palette slice u8, src slice u8) u64", 327} 328 329// The "T1" and "T2" types here are placeholders for generic "slice T" or 330// "table T" types. After tokenizing (but before parsing) these XxxFunc strings 331// (e.g. in the lang/check package), replace "T1" and "T2" with "†" or "‡" 332// daggers, to avoid collision with a user-defined "T1" or "T2" type. 333 334const ( 335 GenericOldName1 = t.IDT1 336 GenericOldName2 = t.IDT2 337 GenericNewName1 = t.IDDagger1 338 GenericNewName2 = t.IDDagger2 339) 340 341var SliceFuncs = []string{ 342 "T1.copy_from_slice!(s T1) u64", 343 "T1.length() u64", 344 "T1.prefix(up_to u64) T1", 345 "T1.suffix(up_to u64) T1", 346} 347 348var TableFuncs = []string{ 349 "T2.height() u64", 350 "T2.stride() u64", 351 "T2.width() u64", 352 353 "T2.row(y u32) T1", 354} 355