| ... | ... | @@ -6421,7 +6421,53 @@ fn asmExpr( |
| 6421 | 6421 | const asm_source = switch (node_tags[full.ast.template]) { |
| 6422 | 6422 | .string_literal => try astgen.strLitAsString(main_tokens[full.ast.template]), |
| 6423 | 6423 | .multiline_string_literal => try astgen.strLitNodeAsString(full.ast.template), |
| 6424 | | else => return astgen.failNode(full.ast.template, "assembly code must use string literal syntax", .{}), |
| 6424 | else => { |
| 6425 | // stage1 allows this, and until we do another design iteration on inline assembly |
| 6426 | // in stage2 to improve support for the various needed use cases, we allow inline |
| 6427 | // assembly templates to be an expression. Once stage2 addresses the real world needs |
| 6428 | // of people using inline assembly (primarily OS developers) then we can re-institute |
| 6429 | // the rule into AstGen that assembly code must use string literal syntax. |
| 6430 | //return astgen.failNode(full.ast.template, "assembly code must use string literal syntax", .{}), |
| 6431 | |
| 6432 | // This code emits ZIR for |
| 6433 | // `@compileError("assembly code must use string literal syntax")` |
| 6434 | // which allows it to make it to stage1 but gives the error for stage2. |
| 6435 | const string_bytes = &astgen.string_bytes; |
| 6436 | const str_index = @intCast(u32, string_bytes.items.len); |
| 6437 | try string_bytes.appendSlice(astgen.gpa, "assembly code must use string literal syntax"); |
| 6438 | const key = string_bytes.items[str_index..]; |
| 6439 | const gop = try astgen.string_table.getOrPutContextAdapted(astgen.gpa, @as([]const u8, key), StringIndexAdapter{ |
| 6440 | .bytes = string_bytes, |
| 6441 | }, StringIndexContext{ |
| 6442 | .bytes = string_bytes, |
| 6443 | }); |
| 6444 | const str = if (gop.found_existing) str: { |
| 6445 | string_bytes.shrinkRetainingCapacity(str_index); |
| 6446 | break :str IndexSlice{ |
| 6447 | .index = gop.key_ptr.*, |
| 6448 | .len = @intCast(u32, key.len), |
| 6449 | }; |
| 6450 | } else str: { |
| 6451 | gop.key_ptr.* = str_index; |
| 6452 | // Still need a null byte because we are using the same table |
| 6453 | // to lookup null terminated strings, so if we get a match, it has to |
| 6454 | // be null terminated for that to work. |
| 6455 | try string_bytes.append(astgen.gpa, 0); |
| 6456 | break :str IndexSlice{ |
| 6457 | .index = str_index, |
| 6458 | .len = @intCast(u32, key.len), |
| 6459 | }; |
| 6460 | }; |
| 6461 | const msg = try gz.add(.{ |
| 6462 | .tag = .str, |
| 6463 | .data = .{ .str = .{ |
| 6464 | .start = str.index, |
| 6465 | .len = str.len, |
| 6466 | } }, |
| 6467 | }); |
| 6468 | const result = try gz.addUnNode(.compile_error, msg, node); |
| 6469 | return rvalue(gz, rl, result, node); |
| 6470 | }, |
| 6425 | 6471 | }; |
| 6426 | 6472 | |
| 6427 | 6473 | // See https://github.com/ziglang/zig/issues/215 and related issues discussing |