authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-11-26 10:34:38+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-11-26 18:25:29+02:00
log128034481ab6eb02da4114b4d49ec3cfd4f8451c
tree3c17b89ab0d8418f2f3005af73f838d12ac4037c
parent36849d8a7b5b0ed62d966ea9c402f192ade0cadf
signaturelock-open Commit is signed but in an unrecognized format.

solve recursion in self hosted


8 files changed, 75 insertions(+), 54 deletions(-)

lib/std/event/fs.zig+14-12
......@@ -735,24 +735,26 @@ pub fn Watch(comptime V: type) type {
735735 allocator: *Allocator,
736736
737737 const OsData = switch (builtin.os) {
738 .macosx, .freebsd, .netbsd, .dragonfly => struct {
739 file_table: FileTable,
740 table_lock: event.Lock,
741
742 const FileTable = std.StringHashMap(*Put);
743 const Put = struct {
744 putter_frame: @Frame(kqPutEvents),
745 cancelled: bool = false,
746 value: V,
747 };
748 },
749
738 // TODO https://github.com/ziglang/zig/issues/3778
739 .macosx, .freebsd, .netbsd, .dragonfly => KqOsData,
750740 .linux => LinuxOsData,
751741 .windows => WindowsOsData,
752742
753743 else => @compileError("Unsupported OS"),
754744 };
755745
746 const KqOsData = struct {
747 file_table: FileTable,
748 table_lock: event.Lock,
749
750 const FileTable = std.StringHashMap(*Put);
751 const Put = struct {
752 putter_frame: @Frame(kqPutEvents),
753 cancelled: bool = false,
754 value: V,
755 };
756 };
757
756758 const WindowsOsData = struct {
757759 table_lock: event.Lock,
758760 dir_table: DirTable,
src-self-hosted/compilation.zig+32-20
......@@ -133,7 +133,7 @@ pub const Compilation = struct {
133133 zig_std_dir: []const u8,
134134
135135 /// lazily created when we need it
136 tmp_dir: event.Future(BuildError![]u8),
136 tmp_dir: event.Future(BuildError![]u8) = event.Future(BuildError![]u8).init(),
137137
138138 version_major: u32 = 0,
139139 version_minor: u32 = 0,
......@@ -158,7 +158,7 @@ pub const Compilation = struct {
158158
159159 /// functions that have their own objects that we need to link
160160 /// it uses an optional pointer so that tombstone removals are possible
161 fn_link_set: event.Locked(FnLinkSet),
161 fn_link_set: event.Locked(FnLinkSet) = event.Locked(FnLinkSet).init(FnLinkSet.init()),
162162
163163 pub const FnLinkSet = std.TailQueue(?*Value.Fn);
164164
......@@ -227,9 +227,9 @@ pub const Compilation = struct {
227227 /// need to wait on this group before deinitializing
228228 deinit_group: event.Group(void),
229229
230 // destroy_frame: @Frame(createAsync),
231 // main_loop_frame: @Frame(Compilation.mainLoop),
232 main_loop_future: event.Future(void),
230 destroy_frame: *@Frame(createAsync),
231 main_loop_frame: *@Frame(Compilation.mainLoop),
232 main_loop_future: event.Future(void) = event.Future(void).init(),
233233
234234 have_err_ret_tracing: bool = false,
235235
......@@ -245,6 +245,8 @@ pub const Compilation = struct {
245245
246246 fs_watch: *fs.Watch(*Scope.Root),
247247
248 cancelled: bool = false,
249
248250 const IntTypeTable = std.HashMap(*const Type.Int.Key, *Type.Int, Type.Int.Key.hash, Type.Int.Key.eql);
249251 const ArrayTypeTable = std.HashMap(*const Type.Array.Key, *Type.Array, Type.Array.Key.hash, Type.Array.Key.eql);
250252 const PtrTypeTable = std.HashMap(*const Type.Pointer.Key, *Type.Pointer, Type.Pointer.Key.hash, Type.Pointer.Key.eql);
......@@ -348,7 +350,9 @@ pub const Compilation = struct {
348350 zig_lib_dir: []const u8,
349351 ) !*Compilation {
350352 var optional_comp: ?*Compilation = null;
351 var frame = async createAsync(
353 var frame = try zig_compiler.allocator.create(@Frame(createAsync));
354 errdefer zig_compiler.allocator.destroy(frame);
355 frame.* = async createAsync(
352356 &optional_comp,
353357 zig_compiler,
354358 name,
......@@ -385,15 +389,12 @@ pub const Compilation = struct {
385389 .build_mode = build_mode,
386390 .zig_lib_dir = zig_lib_dir,
387391 .zig_std_dir = undefined,
388 .tmp_dir = event.Future(BuildError![]u8).init(),
389 // .destroy_frame = @frame(),
390 // .main_loop_frame = undefined,
391 .main_loop_future = event.Future(void).init(),
392 .destroy_frame = @frame(),
393 .main_loop_frame = undefined,
392394
393395 .name = undefined,
394396 .llvm_triple = undefined,
395397 .is_static = is_static,
396 .fn_link_set = event.Locked(FnLinkSet).init(FnLinkSet.init()),
397398 .link_libs_list = undefined,
398399
399400 .exported_symbol_names = event.Locked(Decl.Table).init(Decl.Table.init(allocator)),
......@@ -505,7 +506,10 @@ pub const Compilation = struct {
505506 try comp.initTypes();
506507 defer comp.primitive_type_table.deinit();
507508
508 // comp.main_loop_frame = async comp.mainLoop();
509 comp.main_loop_frame = try allocator.create(@Frame(mainLoop));
510 defer allocator.destroy(comp.main_loop_frame);
511
512 comp.main_loop_frame.* = async comp.mainLoop();
509513 // Set this to indicate that initialization completed successfully.
510514 // from here on out we must not return an error.
511515 // This must occur before the first suspend/await.
......@@ -718,8 +722,11 @@ pub const Compilation = struct {
718722 }
719723
720724 pub fn destroy(self: *Compilation) void {
721 // await self.main_loop_frame;
722 // resume self.destroy_frame;
725 const allocator = self.gpa();
726 self.cancelled = true;
727 await self.main_loop_frame;
728 resume self.destroy_frame;
729 allocator.destroy(self.destroy_frame);
723730 }
724731
725732 fn start(self: *Compilation) void {
......@@ -732,7 +739,7 @@ pub const Compilation = struct {
732739
733740 var build_result = self.initialCompile();
734741
735 while (true) {
742 while (!self.cancelled) {
736743 const link_result = if (build_result) blk: {
737744 break :blk self.maybeLink();
738745 } else |err| err;
......@@ -1130,11 +1137,10 @@ pub const Compilation = struct {
11301137 return link_lib;
11311138 }
11321139
1133 /// cancels itself so no need to await or cancel the promise.
11341140 async fn startFindingNativeLibC(self: *Compilation) void {
1135 std.event.Loop.instance.?.yield();
1141 event.Loop.startCpuBoundOperation();
11361142 // we don't care if it fails, we're just trying to kick off the future resolution
1137 _ = (self.zig_compiler.getNativeLibC()) catch return;
1143 _ = self.zig_compiler.getNativeLibC() catch return;
11381144 }
11391145
11401146 /// General Purpose Allocator. Must free when done.
......@@ -1215,7 +1221,10 @@ pub const Compilation = struct {
12151221 node: *ast.Node,
12161222 expected_type: *Type,
12171223 ) !*Value {
1218 const analyzed_code = try comp.genAndAnalyzeCode(tree_scope, scope, node, expected_type);
1224 var frame = try comp.gpa().create(@Frame(genAndAnalyzeCode));
1225 defer comp.gpa().destroy(frame);
1226 frame.* = async comp.genAndAnalyzeCode(tree_scope, scope, node, expected_type);
1227 const analyzed_code = try await frame;
12191228 defer analyzed_code.destroy(comp.gpa());
12201229
12211230 return analyzed_code.getCompTimeResult(comp);
......@@ -1315,12 +1324,15 @@ fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {
13151324 try fn_type.non_key.Normal.variable_list.append(var_scope);
13161325 }
13171326
1318 const analyzed_code = try comp.genAndAnalyzeCode(
1327 var frame = try comp.gpa().create(@Frame(Compilation.genAndAnalyzeCode));
1328 defer comp.gpa().destroy(frame);
1329 frame.* = async comp.genAndAnalyzeCode(
13191330 tree_scope,
13201331 fn_val.child_scope,
13211332 body_node,
13221333 fn_type.key.data.Normal.return_type,
13231334 );
1335 const analyzed_code = try await frame;
13241336 errdefer analyzed_code.destroy(comp.gpa());
13251337
13261338 assert(fn_val.block_scope != null);
src-self-hosted/ir.zig+16-9
......@@ -658,7 +658,7 @@ pub const Inst = struct {
658658 const amt = try align_inst.getAsConstAlign(ira);
659659 break :blk Type.Pointer.Align{ .Override = amt };
660660 } else blk: {
661 break :blk Type.Pointer.Align{ .Abi = {} };
661 break :blk .Abi;
662662 };
663663 const ptr_type = try Type.Pointer.get(ira.irb.comp, Type.Pointer.Key{
664664 .child_type = child_type,
......@@ -1078,6 +1078,14 @@ pub const Builder = struct {
10781078 self.current_basic_block = basic_block;
10791079 }
10801080
1081 pub fn genNodeRecursive(irb: *Builder, node: *ast.Node, scope: *Scope, lval: LVal) Error!*Inst {
1082 const alloc = irb.comp.gpa();
1083 var frame = try alloc.create(@Frame(genNode));
1084 defer alloc.destroy(frame);
1085 frame.* = async irb.genNode(node, scope, lval);
1086 return await frame;
1087 }
1088
10811089 pub async fn genNode(irb: *Builder, node: *ast.Node, scope: *Scope, lval: LVal) Error!*Inst {
10821090 switch (node.id) {
10831091 .Root => unreachable,
......@@ -1157,7 +1165,7 @@ pub const Builder = struct {
11571165 },
11581166 .GroupedExpression => {
11591167 const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", node);
1160 return irb.genNode(grouped_expr.expr, scope, lval);
1168 return irb.genNodeRecursive(grouped_expr.expr, scope, lval);
11611169 },
11621170 .BuiltinCall => return error.Unimplemented,
11631171 .ErrorSetDecl => return error.Unimplemented,
......@@ -1187,14 +1195,13 @@ pub const Builder = struct {
11871195 }
11881196
11891197 fn genCall(irb: *Builder, suffix_op: *ast.Node.SuffixOp, call: *ast.Node.SuffixOp.Op.Call, scope: *Scope) !*Inst {
1190 async fn genCall(irb: *Builder, suffix_op: *ast.Node.SuffixOp, call: *ast.Node.SuffixOp.Op.Call, scope: *Scope) !*Inst {
1191 const fn_ref = try irb.genNode(suffix_op.lhs, scope, .None);
1198 const fn_ref = try irb.genNodeRecursive(suffix_op.lhs.node, scope, .None);
11921199
11931200 const args = try irb.arena().alloc(*Inst, call.params.len);
11941201 var it = call.params.iterator(0);
11951202 var i: usize = 0;
11961203 while (it.next()) |arg_node_ptr| : (i += 1) {
1197 args[i] = try irb.genNode(arg_node_ptr.*, scope, .None);
1204 args[i] = try irb.genNodeRecursive(arg_node_ptr.*, scope, .None);
11981205 }
11991206
12001207 //bool is_async = node->data.fn_call_expr.is_async;
......@@ -1239,7 +1246,7 @@ pub const Builder = struct {
12391246 //} else {
12401247 // align_value = nullptr;
12411248 //}
1242 const child_type = try irb.genNode(prefix_op.rhs, scope, .None);
1249 const child_type = try irb.genNodeRecursive(prefix_op.rhs, scope, .None);
12431250
12441251 //uint32_t bit_offset_start = 0;
12451252 //if (node->data.pointer_type.bit_offset_start != nullptr) {
......@@ -1438,7 +1445,7 @@ pub const Builder = struct {
14381445 child_scope = &defer_child_scope.base;
14391446 continue;
14401447 }
1441 const statement_value = try irb.genNode(statement_node, child_scope, .None);
1448 const statement_value = try irb.genNodeRecursive(statement_node, child_scope, .None);
14421449
14431450 is_continuation_unreachable = statement_value.isNoReturn();
14441451 if (is_continuation_unreachable) {
......@@ -1534,7 +1541,7 @@ pub const Builder = struct {
15341541
15351542 const outer_scope = irb.begin_scope.?;
15361543 const return_value = if (control_flow_expr.rhs) |rhs| blk: {
1537 break :blk try irb.genNode(rhs, scope, .None);
1544 break :blk try irb.genNodeRecursive(rhs, scope, .None);
15381545 } else blk: {
15391546 break :blk try irb.buildConstVoid(scope, src_span, true);
15401547 };
......@@ -1713,7 +1720,7 @@ pub const Builder = struct {
17131720 };
17141721 if (generate) {
17151722 const defer_expr_scope = defer_scope.defer_expr_scope;
1716 const instruction = try irb.genNode(
1723 const instruction = try irb.genNodeRecursive(
17171724 defer_expr_scope.expr_node,
17181725 &defer_expr_scope.base,
17191726 .None,
src-self-hosted/libc_installation.zig+1-1
......@@ -400,7 +400,7 @@ fn ccPrintFileName(allocator: *Allocator, o_file: []const u8, want_dirname: bool
400400 const argv = [_][]const u8{ cc_exe, arg1 };
401401
402402 // TODO This simulates evented I/O for the child process exec
403 std.event.Loop.instance.?.yield();
403 event.Loop.startCpuBoundOperation();
404404 const errorable_result = std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024);
405405 const exec_result = if (std.debug.runtime_safety) blk: {
406406 break :blk errorable_result catch unreachable;
src-self-hosted/link.zig+4-5
......@@ -623,16 +623,15 @@ fn constructLinkerArgsWasm(ctx: *Context) void {
623623}
624624
625625fn addFnObjects(ctx: *Context) !void {
626 // at this point it's guaranteed nobody else has this lock, so we circumvent it
627 // and avoid having to be an async function
628 const fn_link_set = &ctx.comp.fn_link_set.private_data;
626 const held = ctx.comp.fn_link_set.acquire();
627 defer held.release();
629628
630 var it = fn_link_set.first;
629 var it = held.value.first;
631630 while (it) |node| {
632631 const fn_val = node.data orelse {
633632 // handle the tombstone. See Value.Fn.destroy.
634633 it = node.next;
635 fn_link_set.remove(node);
634 held.value.remove(node);
636635 ctx.comp.gpa().destroy(node);
637636 continue;
638637 };
src-self-hosted/main.zig+6-5
......@@ -127,7 +127,7 @@ pub fn main() !void {
127127 try stderr.print("unknown command: {}\n\n", args[1]);
128128 try stderr.write(usage);
129129 process.argsFree(allocator, args);
130 defer process.exit(1);
130 process.exit(1);
131131}
132132
133133const usage_build_generic =
......@@ -467,7 +467,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
467467
468468fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void {
469469 var count: usize = 0;
470 while (true) { // TODO(Vexu)
470 while (!comp.cancelled) {
471471 const build_event = comp.events.get();
472472 count += 1;
473473
......@@ -545,7 +545,7 @@ fn parseLibcPaths(allocator: *Allocator, libc: *LibCInstallation, libc_paths_fil
545545 "Try running `zig libc` to see an example for the native target.\n",
546546 libc_paths_file,
547547 @errorName(err),
548 ) catch process.exit(1);
548 ) catch {};
549549 process.exit(1);
550550 };
551551}
......@@ -568,7 +568,7 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {
568568 defer zig_compiler.deinit();
569569
570570 const libc = zig_compiler.getNativeLibC() catch |err| {
571 stderr.print("unable to find libc: {}\n", @errorName(err)) catch process.exit(1);
571 stderr.print("unable to find libc: {}\n", @errorName(err)) catch {};
572572 process.exit(1);
573573 };
574574 libc.render(stdout) catch process.exit(1);
......@@ -706,7 +706,8 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
706706 while (try it.next()) |entry| {
707707 if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) {
708708 const full_path = try fs.path.join(fmt.allocator, [_][]const u8{ file_path, entry.name });
709 try group.call(fmtPath, fmt, full_path, check_mode);
709 @panic("TODO https://github.com/ziglang/zig/issues/3777");
710 // try group.call(fmtPath, fmt, full_path, check_mode);
710711 }
711712 }
712713 return group.wait();
src-self-hosted/util.zig+1-1
......@@ -167,7 +167,7 @@ pub fn getDarwinArchString(self: Target) [:0]const u8 {
167167 .powerpc64 => return "ppc64",
168168 .powerpc64le => return "ppc64le",
169169 // @tagName should be able to return sentinel terminated slice
170 else => @panic("TODO"), //return @tagName(arch),
170 else => @panic("TODO https://github.com/ziglang/zig/issues/3779"), //return @tagName(arch),
171171 }
172172}
173173
src-self-hosted/value.zig+1-1
......@@ -350,7 +350,7 @@ pub const Value = struct {
350350 .mut = mut,
351351 .vol = Type.Pointer.Vol.Non,
352352 .size = size,
353 .alignment = Type.Pointer.Align.Abi,
353 .alignment = .Abi,
354354 });
355355 var ptr_type_consumed = false;
356356 errdefer if (!ptr_type_consumed) ptr_type.base.base.deref(comp);