also looking at this
fix(lexer): size the SIMD identifier scan by lane count, not byte size
#625
1 file
+10
-3
Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.
| @@ -320,6 +320,13 @@ pub const Lexer = struct { | ||
| 320 | 320 | /// original boundary. The scalar tail also covers short identifiers. |
| 321 | 321 | inline fn consumeAsciiIdentPart(self: *Lexer) void { |
| 322 | 322 | const Block = @Vector(8, u8); |
| 323 | // Lane count, taken from the type so the two cannot drift. Deliberately | |
| 324 | // not the vector's byte size: a vector is padded up to its alignment, | |
| 325 | // so that is 16 on x86_64 and 8 on aarch64. Sizing the loop by it | |
| 326 | // happened to match the lane count on one target and not the other, | |
| 327 | // where it does not even compile — slicing 16 bytes to coerce into an | |
| 328 | // 8-lane vector is `expected type '@Vector(8, u8)', found '[16]u8'`. | |
| 329 | const lanes = @typeInfo(Block).vector.len; | |
| 323 | 330 | const lower_a: Block = @splat('a'); |
| 324 | 331 | const lower_z: Block = @splat('z'); |
| 325 | 332 | const upper_a: Block = @splat('A'); |
| @@ -328,14 +335,14 @@ pub const Lexer = struct { | ||
| 328 | 335 | const digit_9: Block = @splat('9'); |
| 329 | 336 | const underscore: Block = @splat('_'); |
| 330 | 337 | const dollar: Block = @splat('$'); |
| 331 | while (self.src.len - self.i >= @sizeOf(Block)) { | |
| 332 | const bytes: Block = self.src[self.i..][0..@sizeOf(Block)].*; | |
| 338 | while (self.src.len - self.i >= lanes) { | |
| 339 | const bytes: Block = self.src[self.i..][0..lanes].*; | |
| 333 | 340 | const valid = ((bytes >= lower_a) & (bytes <= lower_z)) | |
| 334 | 341 | ((bytes >= upper_a) & (bytes <= upper_z)) | |
| 335 | 342 | ((bytes >= digit_0) & (bytes <= digit_9)) | |
| 336 | 343 | (bytes == underscore) | (bytes == dollar); |
| 337 | 344 | if (!@reduce(.And, valid)) break; |
| 338 | self.i += @sizeOf(Block); | |
| 345 | self.i += lanes; | |
| 339 | 346 | } |
| 340 | 347 | while (self.i < self.src.len and isIdentPart(self.src[self.i])) self.i += 1; |
| 341 | 348 | } |