Commit 2ae72c6f09
Changed files (5)
lib/std/start.zig
@@ -83,7 +83,7 @@ fn _start2() callconv(.Naked) noreturn {
exit2(0);
}
-fn exit2(code: u8) noreturn {
+fn exit2(code: usize) noreturn {
switch (builtin.stage2_arch) {
.x86_64 => {
asm volatile ("syscall"
src/Module.zig
@@ -3273,6 +3273,10 @@ pub fn analyzeExport(
const owner_decl = scope.ownerDecl().?;
+ log.debug("exporting Decl '{s}' as symbol '{s}' from Decl '{s}'", .{
+ exported_decl.name, borrowed_symbol_name, owner_decl.name,
+ });
+
new_export.* = .{
.options = .{ .name = symbol_name },
.src = src,
src/Sema.zig
@@ -1617,6 +1617,18 @@ fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Inner
return sema.analyzeBlockBody(parent_block, src, &child_block, merges);
}
+fn resolveBlockBody(
+ sema: *Sema,
+ parent_block: *Scope.Block,
+ src: LazySrcLoc,
+ child_block: *Scope.Block,
+ body: []const Zir.Inst.Index,
+ merges: *Scope.Block.Merges,
+) InnerError!*Inst {
+ _ = try sema.analyzeBody(child_block, body);
+ return sema.analyzeBlockBody(parent_block, src, child_block, merges);
+}
+
fn analyzeBlockBody(
sema: *Sema,
parent_block: *Scope.Block,
@@ -1711,11 +1723,23 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!
const decl_name = sema.code.nullTerminatedString(extra.decl_name);
const decl = try sema.lookupIdentifier(block, lhs_src, decl_name);
const options = try sema.resolveInstConst(block, rhs_src, extra.options);
+ const struct_obj = options.ty.castTag(.@"struct").?.data;
+ const fields = options.val.castTag(.@"struct").?.data[0..struct_obj.fields.count()];
+ const name_index = struct_obj.fields.getIndex("name").?;
+ const linkage_index = struct_obj.fields.getIndex("linkage").?;
+ const section_index = struct_obj.fields.getIndex("section").?;
+ const export_name = try fields[name_index].toAllocatedBytes(sema.arena);
+ const linkage = fields[linkage_index].toEnum(
+ struct_obj.fields.items()[linkage_index].value.ty,
+ std.builtin.GlobalLinkage,
+ );
- // TODO respect the name, linkage, and section options. Until then we export
- // as the decl name.
- _ = options;
- const export_name = mem.spanZ(decl.name);
+ if (linkage != .Strong) {
+ return sema.mod.fail(&block.base, src, "TODO: implement exporting with non-strong linkage", .{});
+ }
+ if (!fields[section_index].isNull()) {
+ return sema.mod.fail(&block.base, src, "TODO: implement exporting with linksection", .{});
+ }
try sema.mod.analyzeExport(&block.base, src, export_name, decl);
}
@@ -3600,7 +3624,39 @@ fn analyzeSwitch(
}),
}
- if (try sema.resolveDefinedValue(block, src, operand)) |operand_val| {
+ const block_inst = try sema.arena.create(Inst.Block);
+ block_inst.* = .{
+ .base = .{
+ .tag = Inst.Block.base_tag,
+ .ty = undefined, // Set after analysis.
+ .src = src,
+ },
+ .body = undefined,
+ };
+
+ var child_block: Scope.Block = .{
+ .parent = block,
+ .sema = sema,
+ .src_decl = block.src_decl,
+ .instructions = .{},
+ // TODO @as here is working around a stage1 miscompilation bug :(
+ .label = @as(?Scope.Block.Label, Scope.Block.Label{
+ .zir_block = switch_inst,
+ .merges = .{
+ .results = .{},
+ .br_list = .{},
+ .block_inst = block_inst,
+ },
+ }),
+ .inlining = block.inlining,
+ .is_comptime = block.is_comptime,
+ };
+ const merges = &child_block.label.?.merges;
+ defer child_block.instructions.deinit(gpa);
+ defer merges.results.deinit(gpa);
+ defer merges.br_list.deinit(gpa);
+
+ if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| {
var extra_index: usize = special.end;
{
var scalar_i: usize = 0;
@@ -3614,9 +3670,9 @@ fn analyzeSwitch(
// Validation above ensured these will succeed.
const item = sema.resolveInst(item_ref) catch unreachable;
- const item_val = sema.resolveConstValue(block, .unneeded, item) catch unreachable;
+ const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;
if (operand_val.eql(item_val)) {
- return sema.resolveBody(block, body);
+ return sema.resolveBlockBody(block, src, &child_block, body, merges);
}
}
}
@@ -3636,9 +3692,9 @@ fn analyzeSwitch(
for (items) |item_ref| {
// Validation above ensured these will succeed.
const item = sema.resolveInst(item_ref) catch unreachable;
- const item_val = sema.resolveConstValue(block, item.src, item) catch unreachable;
+ const item_val = sema.resolveConstValue(&child_block, item.src, item) catch unreachable;
if (operand_val.eql(item_val)) {
- return sema.resolveBody(block, body);
+ return sema.resolveBlockBody(block, src, &child_block, body, merges);
}
}
@@ -3650,59 +3706,27 @@ fn analyzeSwitch(
extra_index += 1;
// Validation above ensured these will succeed.
- const first_tv = sema.resolveInstConst(block, .unneeded, item_first) catch unreachable;
- const last_tv = sema.resolveInstConst(block, .unneeded, item_last) catch unreachable;
+ const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable;
+ const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable;
if (Value.compare(operand_val, .gte, first_tv.val) and
Value.compare(operand_val, .lte, last_tv.val))
{
- return sema.resolveBody(block, body);
+ return sema.resolveBlockBody(block, src, &child_block, body, merges);
}
}
extra_index += body_len;
}
}
- return sema.resolveBody(block, special.body);
+ return sema.resolveBlockBody(block, src, &child_block, special.body, merges);
}
if (scalar_cases_len + multi_cases_len == 0) {
- return sema.resolveBody(block, special.body);
+ return sema.resolveBlockBody(block, src, &child_block, special.body, merges);
}
try sema.requireRuntimeBlock(block, src);
- const block_inst = try sema.arena.create(Inst.Block);
- block_inst.* = .{
- .base = .{
- .tag = Inst.Block.base_tag,
- .ty = undefined, // Set after analysis.
- .src = src,
- },
- .body = undefined,
- };
-
- var child_block: Scope.Block = .{
- .parent = block,
- .sema = sema,
- .src_decl = block.src_decl,
- .instructions = .{},
- // TODO @as here is working around a stage1 miscompilation bug :(
- .label = @as(?Scope.Block.Label, Scope.Block.Label{
- .zir_block = switch_inst,
- .merges = .{
- .results = .{},
- .br_list = .{},
- .block_inst = block_inst,
- },
- }),
- .inlining = block.inlining,
- .is_comptime = block.is_comptime,
- };
- const merges = &child_block.label.?.merges;
- defer child_block.instructions.deinit(gpa);
- defer merges.results.deinit(gpa);
- defer merges.br_list.deinit(gpa);
-
// TODO when reworking AIR memory layout make multi cases get generated as cases,
// not as part of the "else" block.
const cases = try sema.arena.alloc(Inst.SwitchBr.Case, scalar_cases_len);
@@ -4614,7 +4638,8 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
}
fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
- const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const zir_datas = sema.code.instructions.items(.data);
+ const inst_data = zir_datas[inst].un_node;
const src = inst_data.src();
const operand = try sema.resolveInst(inst_data.operand);
return sema.mod.constType(sema.arena, src, operand.ty);
@@ -5555,15 +5580,7 @@ fn zirFuncExtended(
const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
const cc_tv = try sema.resolveInstConst(block, cc_src, cc_ref);
- // TODO this needs to resolve other kinds of Value tags rather than
- // assuming the tag will be .enum_field_index.
- const cc_field_index = cc_tv.val.castTag(.enum_field_index).?.data;
- // TODO should `@intToEnum` do this `@intCast` for you?
- const cc = @intToEnum(
- std.builtin.CallingConvention,
- @intCast(@typeInfo(std.builtin.CallingConvention).Enum.tag_type, cc_field_index),
- );
- break :blk cc;
+ break :blk cc_tv.val.toEnum(cc_tv.ty, std.builtin.CallingConvention);
} else .Unspecified;
const align_val: Value = if (small.has_align) blk: {
src/value.zig
@@ -715,6 +715,15 @@ pub const Value = extern union {
};
}
+ /// Asserts the type is an enum type.
+ pub fn toEnum(val: Value, enum_ty: Type, comptime E: type) E {
+ // TODO this needs to resolve other kinds of Value tags rather than
+ // assuming the tag will be .enum_field_index.
+ const field_index = val.castTag(.enum_field_index).?.data;
+ // TODO should `@intToEnum` do this `@intCast` for you?
+ return @intToEnum(E, @intCast(@typeInfo(E).Enum.tag_type, field_index));
+ }
+
/// Asserts the value is an integer.
pub fn toBigInt(self: Value, space: *BigIntSpace) BigIntConst {
switch (self.tag()) {
BRANCH_TODO
@@ -1,5 +1,3 @@
- * implement lazy struct field resolution; don't resolve struct fields until
- they are needed.
* AstGen threadlocal
* extern "foo" for vars and for functions
* namespace decls table can't reference ZIR memory because it can get modified on updates