authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-30 19:41:14-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-30 19:45:08-07:00
logdd62a6d2e8de522187fd096354e7156cca1821c5
treedd87ae2dfd106d7de89f91425377659f1e5f8513
parentf2608df0fb07811ed2d6d41570d1f9ef9a6cd5d6

AstGen: allow non-string-literal inline assembly for stage1

The end-game for inline assembly is that the syntax is more integrated with zig, and it will not allow string concatenation for the assembler code, for the same reasons that Zig does not have a preprocessor. However, inline assembly in zig right now is lacking for a variety of use cases (take a look at the open issues having to do with inline assembly for example), and being able to use comptime expressions to concatenate text is a workaround that real-world users are exploiting to get by in the short term. This commit keeps "assembly code must use string literal syntax" as a compile error when using stage2, but allows it through when using stage1. I expect to revert this commit after making enough improvements to inline assembly that our real world users' needs are satisfied.

1 files changed, 47 insertions(+), 1 deletions(-)

src/AstGen.zig+47-1
......@@ -6421,7 +6421,53 @@ fn asmExpr(
64216421 const asm_source = switch (node_tags[full.ast.template]) {
64226422 .string_literal => try astgen.strLitAsString(main_tokens[full.ast.template]),
64236423 .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 },
64256471 };
64266472
64276473 // See https://github.com/ziglang/zig/issues/215 and related issues discussing