aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-11-30 19:41:14 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-11-30 19:45:08 -0700
commitdd62a6d2e8de522187fd096354e7156cca1821c5 (patch)
treedd87ae2dfd106d7de89f91425377659f1e5f8513 /src
parentf2608df0fb07811ed2d6d41570d1f9ef9a6cd5d6 (diff)
downloadzig-dd62a6d2e8de522187fd096354e7156cca1821c5.tar.gz
zig-dd62a6d2e8de522187fd096354e7156cca1821c5.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig48
1 files changed, 47 insertions, 1 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index c7fe1e7872..e677320e03 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -6421,7 +6421,53 @@ fn asmExpr(
const asm_source = switch (node_tags[full.ast.template]) {
.string_literal => try astgen.strLitAsString(main_tokens[full.ast.template]),
.multiline_string_literal => try astgen.strLitNodeAsString(full.ast.template),
- else => return astgen.failNode(full.ast.template, "assembly code must use string literal syntax", .{}),
+ else => {
+ // stage1 allows this, and until we do another design iteration on inline assembly
+ // in stage2 to improve support for the various needed use cases, we allow inline
+ // assembly templates to be an expression. Once stage2 addresses the real world needs
+ // of people using inline assembly (primarily OS developers) then we can re-institute
+ // the rule into AstGen that assembly code must use string literal syntax.
+ //return astgen.failNode(full.ast.template, "assembly code must use string literal syntax", .{}),
+
+ // This code emits ZIR for
+ // `@compileError("assembly code must use string literal syntax")`
+ // which allows it to make it to stage1 but gives the error for stage2.
+ const string_bytes = &astgen.string_bytes;
+ const str_index = @intCast(u32, string_bytes.items.len);
+ try string_bytes.appendSlice(astgen.gpa, "assembly code must use string literal syntax");
+ const key = string_bytes.items[str_index..];
+ const gop = try astgen.string_table.getOrPutContextAdapted(astgen.gpa, @as([]const u8, key), StringIndexAdapter{
+ .bytes = string_bytes,
+ }, StringIndexContext{
+ .bytes = string_bytes,
+ });
+ const str = if (gop.found_existing) str: {
+ string_bytes.shrinkRetainingCapacity(str_index);
+ break :str IndexSlice{
+ .index = gop.key_ptr.*,
+ .len = @intCast(u32, key.len),
+ };
+ } else str: {
+ gop.key_ptr.* = str_index;
+ // Still need a null byte because we are using the same table
+ // to lookup null terminated strings, so if we get a match, it has to
+ // be null terminated for that to work.
+ try string_bytes.append(astgen.gpa, 0);
+ break :str IndexSlice{
+ .index = str_index,
+ .len = @intCast(u32, key.len),
+ };
+ };
+ const msg = try gz.add(.{
+ .tag = .str,
+ .data = .{ .str = .{
+ .start = str.index,
+ .len = str.len,
+ } },
+ });
+ const result = try gz.addUnNode(.compile_error, msg, node);
+ return rvalue(gz, rl, result, node);
+ },
};
// See https://github.com/ziglang/zig/issues/215 and related issues discussing