Building self-hosted from the original C++ implementation

Context: I am trying to walk Andrew’s steps in this PR and build a contemporary zig.wasm down from the original C++ codebase.

Attempted steps:

  1. Build zig from 28514476ef8c824c3d189d98f23d0f8d23e496ea~1 (bf316e550671cc71eb498b3cf799493627bb0fdc, i.e. the last commit before -fstage1 was removed).
  2. Copy binary and lib somewhere else: mkdir ~/dist; cp -r build/zig2 lib ~/dist
  3. Check out to db023b98a4deef527d4c70d146009f754e9b168d build: introduce -Dwasi-bootstrap option.
  4. ~/dist/zig build -Dwasi-bootstrap. I expect this to build a zig.wasm file, but this panics:
Semantic Analysis [4879] deleteTreeMinStackSizeWithKindHint... thread 2882 panic: reached unreachable code
/x/zig/lib/std/debug.zig:278:14: 0x563455062cd6 in std.debug.assert (zig2)
    if (!ok) unreachable; // assertion failure
             ^
/x/zig/src/type.zig:2478:37: 0x56345540447c in type.Type.hasRuntimeBitsAdvanced (zig2)
                    .eager => assert(struct_obj.haveFieldTypes()),
                                    ^
/x/zig/src/type.zig:2695:38: 0x56345542b12d in type.Type.hasRuntimeBitsIgnoreComptime (zig2)
        return hasRuntimeBitsAdvanced(ty, true, .eager) catch unreachable;
                                     ^
/x/zig/src/codegen/llvm.zig:3190:57: 0x5634556d8b5a in codegen.llvm.DeclGen.lowerPtrElemTy (zig2)
            else => elem_ty.hasRuntimeBitsIgnoreComptime(),
                                                        ^
/x/zig/src/codegen/llvm.zig:2781:59: 0x563455445723 in codegen.llvm.DeclGen.lowerTypeInner (zig2)
                const llvm_elem_ty = try dg.lowerPtrElemTy(ptr_info.pointee_type);
                                                          ^
/x/zig/src/codegen/llvm.zig:2722:43: 0x56345543f431 in codegen.llvm.DeclGen.lowerType (zig2)
        const llvm_ty = try lowerTypeInner(dg, t);
                                          ^
/x/zig/src/codegen/llvm.zig:2771:41: 0x56345544550d in codegen.llvm.DeclGen.lowerTypeInner (zig2)
                        try dg.lowerType(ptr_type),
                                        ^
/x/zig/src/codegen/llvm.zig:2722:43: 0x56345543f431 in codegen.llvm.DeclGen.lowerType (zig2)
        const llvm_ty = try lowerTypeInner(dg, t);
                                          ^
/x/zig/src/codegen/llvm.zig:2985:59: 0x5634554472d3 in codegen.llvm.DeclGen.lowerTypeInner (zig2)
                    const field_llvm_ty = try dg.lowerType(field.ty);
                                                          ^
/x/zig/src/codegen/llvm.zig:2722:43: 0x56345543f431 in codegen.llvm.DeclGen.lowerType (zig2)
        const llvm_ty = try lowerTypeInner(dg, t);
                                          ^
/x/zig/src/codegen/llvm.zig:2985:59: 0x5634554472d3 in codegen.llvm.DeclGen.lowerTypeInner (zig2)
                    const field_llvm_ty = try dg.lowerType(field.ty);
                                                          ^
/x/zig/src/codegen/llvm.zig:2722:43: 0x56345543f431 in codegen.llvm.DeclGen.lowerType (zig2)
        const llvm_ty = try lowerTypeInner(dg, t);
                                          ^
/x/zig/src/codegen/llvm.zig:3193:29: 0x5634556d8bc4 in codegen.llvm.DeclGen.lowerPtrElemTy (zig2)
            try dg.lowerType(elem_ty)
                            ^
/x/zig/src/codegen/llvm.zig:2781:59: 0x563455445723 in codegen.llvm.DeclGen.lowerTypeInner (zig2)
                const llvm_elem_ty = try dg.lowerPtrElemTy(ptr_info.pointee_type);
                                                          ^
/x/zig/src/codegen/llvm.zig:2722:43: 0x56345543f431 in codegen.llvm.DeclGen.lowerType (zig2)
        const llvm_ty = try lowerTypeInner(dg, t);
                                          ^
/x/zig/src/codegen/llvm.zig:5930:45: 0x56345589f607 in codegen.llvm.FuncGen.airFieldParentPtr (zig2)
        const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));
                                            ^
/x/zig/src/codegen/llvm.zig:4633:64: 0x56345586a21b in codegen.llvm.FuncGen.genBody (zig2)
                .field_parent_ptr => try self.airFieldParentPtr(inst),
                                                               ^
/x/zig/src/codegen/llvm.zig:5474:29: 0x563455884af6 in codegen.llvm.FuncGen.airSwitchBr (zig2)
            try self.genBody(case_body);
                            ^
/x/zig/src/codegen/llvm.zig:4555:56: 0x563455867fed in codegen.llvm.FuncGen.genBody (zig2)
                .switch_br      => try self.airSwitchBr(inst),
                                                       ^
/x/zig/src/codegen/llvm.zig:1208:19: 0x563455863038 in codegen.llvm.Object.updateFunc (zig2)
        fg.genBody(air.getMainBody()) catch |err| switch (err) {
                  ^
/x/zig/src/link/Wasm.zig:876:74: 0x5634555c53d7 in link.Wasm.updateFunc (zig2)
    }
                                                                         ^
/x/zig/src/link.zig:566:77: 0x5634553921d5 in link.File.updateFunc (zig2)
            .plan9 => return @fieldParentPtr(Plan9, "base", base).updateFunc(module, func, air, liveness),
                                                                            ^
/x/zig/src/Module.zig:4385:37: 0x563455371e41 in Module.ensureFuncBodyAnalyzed (zig2)
            comp.bin_file.updateFunc(mod, func, air, liveness) catch |err| switch (err) {
                                    ^
/x/zig/src/Compilation.zig:3154:42: 0x56345521fcc3 in Compilation.processOneJob (zig2)
                    const fwd_decl = &decl_emit_h.fwd_decl;
                                         ^
/x/zig/src/Compilation.zig:3092:30: 0x56345520d01f in Compilation.performAllTheWork (zig2)
                .outdated => unreachable,
                             ^
/x/zig/src/Compilation.zig:2401:31: 0x563455205387 in Compilation.update (zig2)
            const decl = module.declPtr(decl_index);
                              ^
/x/zig/src/main.zig:3376:20: 0x5634551935af in main.updateModule (zig2)
    defer errors.deinit(comp.gpa);
                   ^
/x/zig/src/main.zig:3043:17: 0x5634550da3a1 in main.buildOutputType (zig2)
    };
                ^
/x/zig/src/main.zig:230:31: 0x5634550710ab in main.mainArgs (zig2)

                              ^
/x/zig/src/stage1.zig:56:24: 0x563455070a05 in main (zig2)
        stage2.mainArgs(gpa, arena, args) catch unreachable;
                       ^
error: zig...
error: The following command terminated unexpectedly:
/x/zig/build/dist/zig build-exe --stack 33554432 /x/zig/src/main.zig -OReleaseSmall --cache-dir /x/zig/zig-cache --global-cache-dir /root/.cache/zig --name zig -target wasm32-wasi -mcpu generic --pkg-begin build_options /x/zig/zig-cache/options/jivNPNwbviGnCnscXAfCJDcbRqydjv3fwLQrouIYsELM7P7rVuhILPn0WH6mZ9HL --pkg-end -fno-build-id --enable-cache
error: the following build command failed with exit code 6:
/x/zig/zig-cache/o/3ea3dbe97768319770e9733a3257a50a/build /x/zig/build/dist/zig /x/zig /x/zig/zig-cache /root/.cache/zig -Dwasi-bootstrap

I also attempted to build zig.c from 28514476ef8c824c3d189d98f23d0f8d23e496ea (the commit that removes -fstage1), but yielded a quite clearly bogus zig.c, so I guess that wasn’t a thing back then.

Any pointers how to proceed from db023b98a4deef527d4c70d146009f754e9b168d build: introduce -Dwasi-bootstrap option?

1 Like

The last thing I did in that branch before merging it was build a fresh zig1.wasm with the latest tip of the branch, so the commit order is not necessarily correct there for the purposes of reproducing.

You probably need one of the other fixes from the branch in order to avoid tripping that bug, particularly the one in Sema.zig that adds the line:

try sema.queueFullTypeResolution(result_ptr);

This is the case for many of the branches if you are trying to create a bootstrap chain. You might need to solve a little puzzle in each branch to figure out how to rebuild zig1.wasm.

For the real world purposes of bootstrapping, the best solution is for a third party to implement a zig interpreter that assumes -target wasm32-wasi and uses pub const dev = .bootstrap; in the config options in order to produce zig2.c and continue the build from there. This interpreter could be written in Lua or Lisp for example, and only needs to be able to interpret exactly the latest tagged release of Zig. Any tricky one-off functions could be hacked around in this interpreter since it is a bespoke interpreter for this one codebase. Such hacks would not compromise the goal of the interpreter, which is to ensure that zig1.wasm has no hidden logic.

I agree this would be the ideal scenario for easy bootstrapping. However, that entails writing an interpreter, which is more than a few early mornings worth of work.

My goal is to write a script that massages zig repository and creates zig1.wasm from source-only (or using artifacts that it built during the process) without writing an interpreter. Then anyone can run it and confirm that the hash matches whatever is in whatever version they are interested at.

It’s good to know the commit order is not necessarily correct, thank you for the tip. I will now attempt at solving the puzzle. :slight_smile:

1 Like

This is an interesting little project, good luck getting it working! I don’t envy you; zig1.wasm updates can sometimes be quite tricky to get right even on our end, most often because the compiler depends on std.builtin both when building the compiler and when using the compiler, so breaking changes to std.builtin often need to be done in slightly complicated ways (such as my recent changes to std.builtin.CallingConvention; this commit explains what I had to do there). That said, I suppose that shouldn’t impact you too much. So long as we’ve not done too much nasty stuff before, like requiring a specific intermediate commit to build a new zig1.wasm, or reordering commits to perform a zig1.wasm update “before” the corresponding changes, or even just running update-zig1 with uncommitted changes… so long as we’ve not committed too many of those sins, hopefully the commit history can get you most of the way there?

Feel free to ping me here if you have questions about any specific zig1.wasm update in the history which is causing you trouble.

1 Like

I was able to build the first one zig1.wasm.zst quite easily (will post the script later after cleanup). And yes, I got the sense that building zig1.wasm is/was a free reign, assuming the end result is correct. :slight_smile:

Your offer for help is spot-on! :smiley: I feel/hope that after being guided through a few of those incompatibilities, I will be able to proceed myself.

The first issue updating zig1.wasm is Eliminate BoundFn type from the language. Excerpt from the build log:

motiejus@3b3ad0b7b0ab:/x/zig$ build/stage3/bin/zig build                                                                                                                                                            
src/Sema.zig:21970:5: error: switch must handle all possibilities                                                                                                                                                   
    switch (ty.zigTypeTag()) {                                                                                                                                                                                      
    ^~~~~~                                                                                                                                                                                                          
build/stage3/lib/zig/std/builtin.zig:213:5: note: unhandled enumeration value: 'BoundFn'                                                                                                                            
    BoundFn: Fn,                                                                                                                                                                                                    
    ^~~~~~~~~~~                                                                                                                                                                                                     
build/stage3/lib/zig/std/builtin.zig:193:18: note: enum '@typeInfo(builtin.Type).Union.tag_type.?' declared here                                                                                                    
pub const Type = union(enum) {                                                                                                                                                                                      
                 ^~~~~                                                                                                                                                                                              
referenced by:                                                                                                                                                                                                      
    analyzeExport: src/Sema.zig:5460:18                                                                                                                                                                             
    semaDecl: src/Module.zig:4727:25                                                                                                                                                                                
    remaining reference traces hidden; use '-freference-trace' to see all reference traces                                                                                                                          

And this is exactly what happens here: BoundFn was removed from the builtins, but the zig1.wasm, with which I am trying to build a new one, still has it.

@mlugg open for tips.

Oh, this one’s easy – you just need to pass --zig-lib-dir lib here. This is nothing to do with what’s in your zig1.wasm, since there’s nothing particularly special about the standard library, we’re always just treating it like normal source code, so if you’re not using zig1, there aren’t any traces of it left in the compiler you are using! The error message shows the BoundFn: BoundFn field existing in build/stage3/lib, which is the case because that’s an outdated lib directory. So, just pass it --zig-lib-dir lib to use the up-to-date lib directory (i.e. as of this commit) in the repo root.

You’ll probably need to pass --zig-lib-dir like that more often than not; I’d suggest treating it as your default strategy.

Thanks. That was my default (and the only) strategy. :smiley: I got a different compiler error, which looked similar enough, so I didn’t report that. Here we go:

$ build/stage3/bin/zig build --zig-lib-dir $PWD/lib
thread 49 panic: attempt to use null value
Analyzing /x/zig/lib/std/log.zig: log.zig:scoped
      %430 = enum_literal("EnumLiteral") 
    > %431 = extended(reify(%430)) 
      %432 = break_inline(%433, %431)
    For full context, use the command
      zig ast-check -t /x/zig/lib/std/log.zig

  in /x/zig/lib/std/log.zig: log.zig:scoped
    > %433 = param_comptime("scope", {%430..%432}) 
  in /x/zig/lib/std/log.zig: log.zig:default
    > %548 = decl_val("scoped") 
  in /x/zig/lib/std/log.zig: log.zig:warn
    > %559 = decl_val("default") 
  in /x/zig/lib/std/build.zig: build.zig:Builder.addUserInputOption
    > %5774 = field_call_bind(%5772, "warn") 
  in /x/zig/lib/std/build.zig: build.zig:Builder.addUserInputOption
    > %5769 = block({%5770..%5786}) 
  in /x/zig/lib/std/build.zig: build.zig:Builder.addUserInputOption
    > %5616 = switch_block(%5613,
        %5619 => {%5617..%5706},
        %5709 => {%5707..%5765},
        %5767 => {%5768..%5789}) 
  in /x/zig/lib/std/build.zig: build.zig:Builder.addUserInputOption
    > %5526 = block({%5527..%5796}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %496 = try(%493, {%497..%502}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %505 = block({%490..%504}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %476 = block({%477..%528}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %471 = condbr(%470, {%473..%573}, {%530..%574}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %472 = block({%461..%471}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %410 = block({%411..%578}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %407 = condbr(%406, {%409..%2286}, {%580..%2287}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %408 = block({%397..%407}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %394 = block({%395..%2291}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %388 = block({%393..%2292}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %385 = condbr(%384, {%390..%2293}, {%2294}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %386 = block({%377..%385}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %376 = loop({%386, %389}) 
  in /x/zig/lib/build_runner.zig: build_runner.zig:main
    > %41 = block({%42..%2434}) 
  in /x/zig/lib/std/start.zig: start.zig:callMain
    > %3051 = is_non_err(%3050) 
  in /x/zig/lib/std/start.zig: start.zig:callMain
    > %3053 = block({%3046..%3052}) 
  in /x/zig/lib/std/start.zig: start.zig:callMain
    > %3043 = block({%3044..%3184}) 
  in /x/zig/lib/std/start.zig: start.zig:callMain
    > %2953 = switch_block(%2950,
        else => {%3187..%3190},
        %2955 => {%2956..%2969},
        %2971 => {%2972..%2989},
        %2992 => {%2990..%3039},
        %3041 => {%3042..%3186}) 
  in /x/zig/lib/std/start.zig: start.zig:callMain
    > %2937 = block({%2938..%3195}) 
  in /x/zig/lib/std/start.zig: start.zig:initEventLoopAndCallMain
    > %2657 = builtin_call(%2655, %2656, @Zir.Inst.Ref.empty_struct) 
  in /x/zig/lib/std/start.zig: start.zig:initEventLoopAndCallMain
    > %2501 = block({%2502..%2662}) 
  in /x/zig/lib/std/start.zig: start.zig:callMainWithArgs
    > %2288 = call(.auto, %2286, []) 
  in /x/zig/lib/std/start.zig: start.zig:callMainWithArgs
    > %2257 = block({%2258..%2293}) 
  in /x/zig/lib/std/start.zig: start.zig:posixCallMainAndExit
    > %2122 = builtin_call(%2119, %2120, %2121) 
  in /x/zig/lib/std/start.zig: start.zig:posixCallMainAndExit
    > %2114 = call(nodiscard .auto, %2112, [
        {%2115..%2123},
      ]) 
  in /x/zig/lib/std/start.zig: start.zig:posixCallMainAndExit
    > %1750 = block({%1751..%2126}) 

/x/zig/src/Sema.zig:17957:65: 0xf6ca46 in zirReify (zig)
            const child_ty = child_val.toType(&buffer);
                                                                ^
/x/zig/src/Sema.zig:1147:64: 0xca021b in analyzeBodyInner (zig)
                    .reify                 => try sema.zirReify(             block, extended, inst),
                                                               ^
/x/zig/src/Sema.zig:815:45: 0xaceaa1 in analyzeBodyBreak (zig)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
/x/zig/src/Sema.zig:765:50: 0x12f1f73 in resolveBody (zig)
    const break_data = (try sema.analyzeBodyBreak(block, body)) orelse
                                                 ^
/x/zig/src/Sema.zig:8778:33: 0xf84061 in zirParam (zig)
            if (sema.resolveBody(block, body, inst)) |param_ty_inst| {
                                ^
/x/zig/src/Sema.zig:1321:34: 0xca274a in analyzeBodyInner (zig)
                try sema.zirParam(block, inst, true);
                                 ^
/x/zig/src/Sema.zig:815:45: 0xaceaa1 in analyzeBodyBreak (zig)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
/x/zig/src/Module.zig:4635:50: 0xacabaf in semaDecl (zig)
    const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
                                                 ^
/x/zig/src/Module.zig:4256:38: 0x948079 in ensureDeclAnalyzed (zig)
    const type_changed = mod.semaDecl(decl_index) catch |err| switch (err) {
                                     ^
/x/zig/src/Sema.zig:27544:32: 0x133c832 in ensureDeclAnalyzed (zig)
        } else {
                               ^
/x/zig/src/Sema.zig:27586:32: 0xfac831 in analyzeDeclRef (zig)
    return sema.addConstant(
                               ^
/x/zig/src/Sema.zig:27514:45: 0x1305404 in analyzeDeclVal (zig)
    decl_index: Decl.Index,
                                            ^
/x/zig/src/Sema.zig:5729:31: 0xecb146 in zirDeclVal (zig)
    return sema.analyzeDeclVal(block, src, decl);
                              ^
/x/zig/src/Sema.zig:926:65: 0xc95551 in analyzeBodyInner (zig)
            .decl_val                     => try sema.zirDeclVal(block, inst),
                                                                ^
/x/zig/src/Sema.zig:815:45: 0xaceaa1 in analyzeBodyBreak (zig)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
/x/zig/src/Module.zig:4635:50: 0xacabaf in semaDecl (zig)
    const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
                                                 ^
/x/zig/src/Module.zig:4256:38: 0x948079 in ensureDeclAnalyzed (zig)
    const type_changed = mod.semaDecl(decl_index) catch |err| switch (err) {
                                     ^
/x/zig/src/Sema.zig:27544:32: 0x133c832 in ensureDeclAnalyzed (zig)
        } else {
                               ^
/x/zig/src/Sema.zig:27586:32: 0xfac831 in analyzeDeclRef (zig)
    return sema.addConstant(
                               ^
/x/zig/src/Sema.zig:27514:45: 0x1305404 in analyzeDeclVal (zig)
    decl_index: Decl.Index,
                                            ^
/x/zig/src/Sema.zig:5729:31: 0xecb146 in zirDeclVal (zig)
    return sema.analyzeDeclVal(block, src, decl);
                              ^
/x/zig/src/Sema.zig:926:65: 0xc95551 in analyzeBodyInner (zig)
            .decl_val                     => try sema.zirDeclVal(block, inst),
                                                                ^
/x/zig/src/Sema.zig:815:45: 0xaceaa1 in analyzeBodyBreak (zig)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
/x/zig/src/Module.zig:4635:50: 0xacabaf in semaDecl (zig)
    const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
                                                 ^
/x/zig/src/Module.zig:4256:38: 0x948079 in ensureDeclAnalyzed (zig)
    const type_changed = mod.semaDecl(decl_index) catch |err| switch (err) {
                                     ^
/x/zig/src/Sema.zig:27544:32: 0x133c832 in ensureDeclAnalyzed (zig)
        } else {
                               ^
/x/zig/src/Sema.zig:27586:32: 0xfac831 in analyzeDeclRef (zig)
    return sema.addConstant(
                               ^
/x/zig/src/Sema.zig:27514:45: 0x1305404 in analyzeDeclVal (zig)
    decl_index: Decl.Index,
                                            ^
/x/zig/src/Sema.zig:23164:35: 0x165753a in namespaceLookupVal (zig)

                                  ^
/x/zig/src/Sema.zig:22678:56: 0x1308e6f in fieldVal (zig)
                    return sema.failWithOwnedErrorMsg(msg);
                                                       ^
/x/zig/src/Sema.zig:22997:37: 0x130aa55 in fieldCallBind (zig)
                        decl_type.fnParamLen() >= 1)
                                    ^
/x/zig/src/Sema.zig:9007:30: 0xed1517 in zirFieldCallBind (zig)
    return sema.fieldCallBind(block, src, object_ptr, field_name, field_name_src);
                             ^
/x/zig/src/Sema.zig:948:71: 0xc9686e in analyzeBodyInner (zig)
            .field_call_bind              => try sema.zirFieldCallBind(block, inst),
                                                                      ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:779:30: 0x1331e4b in analyzeBodyRuntimeBreak (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Sema.zig:10567:45: 0xeea8fc in zirSwitchBlock (zig)

                                            ^
/x/zig/src/Sema.zig:981:69: 0xc9852b in analyzeBodyInner (zig)
            .switch_block                 => try sema.zirSwitchBlock(block, inst),
                                                                    ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:798:30: 0xe7ade8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Module.zig:5659:43: 0xc76eca in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                                          ^
/x/zig/src/Module.zig:4342:40: 0xaae07d in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func, sema_arena) catch |err| switch (err) {
                                       ^
/x/zig/src/Sema.zig:27555:36: 0x13c4827 in ensureFuncBodyAnalyzed (zig)
        try ty.copy(anon_decl.arena()),
                                   ^
/x/zig/src/Sema.zig:29908:44: 0xfc1fa9 in resolveInferredErrorSet (zig)
    }
                                           ^
/x/zig/src/Sema.zig:27834:49: 0xf8dc11 in analyzeIsNonErrComptimeOnly (zig)
        } else {
                                                ^
/x/zig/src/Sema.zig:16392:60: 0xf8cc0d in zirTry (zig)
        // no breaks from the body possible, and that the body is noreturn.
                                                           ^
/x/zig/src/Sema.zig:1603:67: 0xca6b43 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirTry(block, inst);
                                                                  ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:779:30: 0x1331e4b in analyzeBodyRuntimeBreak (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Sema.zig:16341:37: 0xf8bb31 in zirCondbr (zig)

                                    ^
/x/zig/src/Sema.zig:1557:61: 0xca5577 in analyzeBodyInner (zig)
                if (!block.is_comptime) break sema.zirCondbr(block, inst);
                                                            ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:779:30: 0x1331e4b in analyzeBodyRuntimeBreak (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Sema.zig:16341:37: 0xf8bb31 in zirCondbr (zig)

                                    ^
/x/zig/src/Sema.zig:1557:61: 0xca5577 in analyzeBodyInner (zig)
                if (!block.is_comptime) break sema.zirCondbr(block, inst);
                                                            ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:779:30: 0x1331e4b in analyzeBodyRuntimeBreak (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Sema.zig:16341:37: 0xf8bb31 in zirCondbr (zig)

                                    ^
/x/zig/src/Sema.zig:1557:61: 0xca5577 in analyzeBodyInner (zig)
                if (!block.is_comptime) break sema.zirCondbr(block, inst);
                                                            ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:798:30: 0xe7ade8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Sema.zig:5065:25: 0xf88908 in zirLoop (zig)
    try sema.analyzeBody(&loop_block, body);
                        ^
/x/zig/src/Sema.zig:1435:68: 0xca3b60 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirLoop(block, inst);
                                                                   ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:798:30: 0xe7ade8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Module.zig:5659:43: 0xc76eca in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                                          ^
/x/zig/src/Module.zig:4342:40: 0xaae07d in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func, sema_arena) catch |err| switch (err) {
                                       ^
/x/zig/src/Sema.zig:27555:36: 0x13c4827 in ensureFuncBodyAnalyzed (zig)
        try ty.copy(anon_decl.arena()),
                                   ^
/x/zig/src/Sema.zig:29908:44: 0xfc1fa9 in resolveInferredErrorSet (zig)
    }
                                           ^
/x/zig/src/Sema.zig:27834:49: 0xf8dc11 in analyzeIsNonErrComptimeOnly (zig)
        } else {
                                                ^
/x/zig/src/Sema.zig:27861:56: 0x13123bc in analyzeIsNonErr (zig)
) CompileError!Air.Inst.Ref {
                                                       ^
/x/zig/src/Sema.zig:16290:53: 0xed6e5b in zirIsNonErr (zig)
    const inst_data = sema.code.instructions.items(.data)[inst].un_node;
                                                    ^
/x/zig/src/Sema.zig:959:66: 0xc97201 in analyzeBodyInner (zig)
            .is_non_err                   => try sema.zirIsNonErr(block, inst),
                                                                 ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:10434:49: 0xee769a in zirSwitchBlock (zig)
        {
                                                ^
/x/zig/src/Sema.zig:981:69: 0xc9852b in analyzeBodyInner (zig)
            .switch_block                 => try sema.zirSwitchBlock(block, inst),
                                                                    ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:798:30: 0xe7ade8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Sema.zig:6597:55: 0x12fb37f in analyzeCall (zig)
                sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
                                                      ^
/x/zig/src/Sema.zig:20881:28: 0xf292b1 in zirBuiltinCall (zig)
    const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
                           ^
/x/zig/src/Sema.zig:1038:69: 0xc9b6fc in analyzeBodyInner (zig)
            .builtin_call                 => try sema.zirBuiltinCall(block, inst),
                                                                    ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:798:30: 0xe7ade8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Sema.zig:6597:55: 0x12fb37f in analyzeCall (zig)
                sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
                                                      ^
/x/zig/src/Sema.zig:6145:32: 0xec6817 in zirCall (zig)
        return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src);
                               ^
/x/zig/src/Sema.zig:916:62: 0xc94c28 in analyzeBodyInner (zig)
            .call                         => try sema.zirCall(block, inst),
                                                             ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:798:30: 0xe7ade8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Sema.zig:6597:55: 0x12fb37f in analyzeCall (zig)
                sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
                                                      ^
/x/zig/src/Sema.zig:20881:28: 0xf292b1 in zirBuiltinCall (zig)
    const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
                           ^
/x/zig/src/Sema.zig:1038:69: 0xc9b6fc in analyzeBodyInner (zig)
            .builtin_call                 => try sema.zirBuiltinCall(block, inst),
                                                                    ^
/x/zig/src/Sema.zig:815:45: 0xaceaa1 in analyzeBodyBreak (zig)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
/x/zig/src/Sema.zig:765:50: 0x12f1f73 in resolveBody (zig)
    const break_data = (try sema.analyzeBodyBreak(block, body)) orelse
                                                 ^
/x/zig/src/Sema.zig:6094:63: 0xec6332 in zirCall (zig)
        const resolved = try sema.resolveBody(block, args_body[arg_start..arg_end], inst);
                                                              ^
/x/zig/src/Sema.zig:916:62: 0xc94c28 in analyzeBodyInner (zig)
            .call                         => try sema.zirCall(block, inst),
                                                             ^
/x/zig/src/Sema.zig:5240:34: 0x1336a09 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/x/zig/src/Sema.zig:5223:85: 0xf894cc in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/x/zig/src/Sema.zig:1449:69: 0xca40e1 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/x/zig/src/Sema.zig:798:30: 0xe7ade8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/x/zig/src/Module.zig:5659:43: 0xc76eca in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                                          ^
/x/zig/src/Module.zig:4342:40: 0xaae07d in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func, sema_arena) catch |err| switch (err) {
                                       ^
/x/zig/src/Compilation.zig:3098:42: 0xaabbfc in processOneJob (zig)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
/x/zig/src/Compilation.zig:3036:30: 0x98c3a4 in performAllTheWork (zig)
            try processOneJob(comp, work_item);
                             ^
/x/zig/src/Compilation.zig:2360:31: 0x987e63 in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/x/zig/src/main.zig:3423:20: 0x9b661d in updateModule (zig)
    try comp.update();
                   ^
/x/zig/src/main.zig:4027:21: 0x8a0869 in cmdBuild (zig)
        updateModule(gpa, comp, .none) catch |err| switch (err) {
                    ^
/x/zig/src/main.zig:286:24: 0x87253d in mainArgs (zig)
        return cmdBuild(gpa, arena, cmd_args);
                       ^
/x/zig/src/main.zig:199:20: 0x871135 in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/x/zig/lib/std/start.zig:614:37: 0x873767 in main (zig)
            const result = root.main() catch |err| {
                                    ^

Stack trace seems to point here, but the reason/remedy are far from obvious. :slight_smile:

Where did the stage3 we’re using here come from?

What’s happening here is that since BoundFn was removed, the following tags in std.builtin.Type had their indices shifted. That mostly doesn’t matter, since the ones after it mostly aren’t exercised by the compiler build process – however, it looks like the build system is doing @Type(.EnumLiteral), and that tag does indeed come after .BoundFn.

I don’t think the actual build-exe of the compiler will care about that tag being offset, since AFAICT we didn’t do @Type(.EnumLiteral) anywhere in the compiler itself in that version (we used the slightly sillier @TypeOf(.EnumLiteral) instead). So, if you bypass the build system to get a post-change build of Zig, it’ll probably work. The easiest way to do that is to take your latest zig1.wasm, and run a full bootstrap on this commit (with the CMake script), since that has a fixed build-exe command for the initial zig2 build. In general, running the bootstrap process (i.e. zig1.wasmzig1.czig1 which produces zig2.czig2 which produces zig3) is what’s most likely to work when you have issues, because it exercises a much smaller amount of compiler functionality; it bypasses the build system entirely for the initial build, and only builds a quite limited compiler.

So, here’s what I think should work:

  • Have a zig1.wasm from whenever the last update was before this one
  • With this BoundFn commit checked out, run the full CMake bootstrap
  • With the generated stage3/bin/zig, recreate zig1.wasm
2 Likes

Thank you for the explanation. Indeed I needed to do a few, tweaks (not that I could come up with them without your tips!) to the compiler:

 lib/std/log.zig     | 4 ++--
 src/link/strtab.zig | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/std/log.zig b/lib/std/log.zig
index 9ebe85c004..f174946565 100644
--- a/lib/std/log.zig
+++ b/lib/std/log.zig
@@ -121,7 +121,7 @@ else
 
 fn log(
     comptime message_level: Level,
-    comptime scope: @Type(.EnumLiteral),
+    comptime scope: @TypeOf(.EnumLiteral),
     comptime format: []const u8,
     args: anytype,
 ) void {
@@ -167,7 +167,7 @@ pub fn defaultLog(
 
 /// Returns a scoped logging namespace that logs all messages using the scope
 /// provided here.
-pub fn scoped(comptime scope: @Type(.EnumLiteral)) type {
+pub fn scoped(comptime scope: @TypeOf(.EnumLiteral)) type {
     return struct {
         /// Log an error message. This log level is intended to be used
         /// when something has gone wrong. This might be recoverable or might
diff --git a/src/link/strtab.zig b/src/link/strtab.zig
index abb58defef..2048aa216e 100644
--- a/src/link/strtab.zig
+++ b/src/link/strtab.zig
@@ -5,7 +5,7 @@ const Allocator = mem.Allocator;
 const StringIndexAdapter = std.hash_map.StringIndexAdapter;
 const StringIndexContext = std.hash_map.StringIndexContext;
 
-pub fn StringTable(comptime log_scope: @Type(.EnumLiteral)) type {
+pub fn StringTable(comptime log_scope: @TypeOf(.EnumLiteral)) type {
     return struct {
         const Self = @This();
 
-- 
2.44.1

And now I am past BoundFn stage. Thanks!

Onwards!

1 Like

I am past BoundFn stage, then another one, and now ended up here:

commit 7b2a936173165002105ba5e76bed69654e132fea
Author: Veikka Tuominen <git@vexu.eu>
Date:   2022-12-12T15:32:37+02:00

    remove `stack` option from `@call`

If I try to build zig1.wasm with full bootstrap (cmake ..; make -j), it will fail this way:

motiejus@7e8111f66616:/x/zig-0.10.0-747-g7b2a936173/build$ make -j$(nproc)
[ 10%] Built target zig-wasm2c
[ 50%] Built target zigcpp
[ 70%] Built target zig1
[ 75%] Running zig1.wasm to produce /x/zig-0.10.0-747-g7b2a936173/build/zig2.c
lib/std/builtin.zig is corrupt and missing 'CallOptions'Aborted (core dumped)
make[2]: *** [CMakeFiles/zig2.dir/build.make:490: zig2.c] Error 134
make[2]: *** Deleting file 'zig2.c'
make[1]: *** [CMakeFiles/Makefile2:169: CMakeFiles/zig2.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

Which makes sense, since, well, CallOptions were removed in that commit (as well as completely changed @call semantics).

Looking forward to the next tip. :slight_smile:

1 Like

For that one I think you can do the following:

  • Check out 7b2a936173165002105ba5e76bed69654e132fea
  • Add the following declaration to lib/std/builtin.zig:
    pub const CallOptions = struct {
        modifier: CallModifier = .auto,
        stack: ?[]align(std.Target.stack_align) u8 = null,
    };
    
  • Update zig1.wasm
  • All done (you can revert the change)

The trick here is that since a type was removed rather than changed, you can just include both declarations in std.builtin when building the compiler here. You want 7b2a936173165002105ba5e76bed69654e132fea rather than 08b2d491bcd8c79c68495267cc71967661caea1e because the compiler you’re using to build zig1.wasm expects the old usage, so we want the commit before usages were changed.

(By the way, I hope you’re noting down what you had to do for each of these; it’d be nice to have a way to reproduce the full bootstrap path!)

2 Likes

This was very helpful! I needed another silly fix for zig3 in callsites, akin to:

    if (@import("builtin").zig_backend == .stage2_c) {
        return @call(.{ .modifier = .always_inline }, callMain, .{});
    } else {
        return @call(.always_inline, callMain, .{});
    }

Sure! It’s all here: motiejus/zig-repro - zig-repro - gitea: Gitea Service

2 Likes

I needed another silly fix for zig3 in callsites

Hm, that shouldn’t be necessary with the right order of operations. Let me be a little more specific:

  • Have zig3 from some commit <= 7b2a936173165002105ba5e76bed69654e132fea
  • With that commit checked out, apply my patch
  • Update zig1.wasm
  • Before building another zig3, check out, at a minimum, 08b2d491bcd8c79c68495267cc71967661caea1e to update the usages

Because just updating zig1.wasm won’t use the C backend, your patch shouldn’t be necessary; you can just let the next commit update all the usages before you try to make any updated zig3.

Sure! It’s all here:

Amazing, thanks for the link!

2 Likes

I’ve got 0.11.0, so I will be closing this.

My end-goal is 0.13.0. Once I get there, I will compare the upstream’s zig1.wasm to the one that my script generates, and will report findings somewhere in this forum.

Thanks @mlugg , your help was invaluable to get this off the ground!

1 Like

Nice! Hopefully you won’t have long to go before you reach master; I had a quick glance over the commit log and it doesn’t look like there are too many updates past this point. Let me know if you hit any more issues!

2 Likes

EDIT: scratch that, I was able to reconstruct the cmdline arguments from building the older branches. :slight_smile:

Hilton Chain from guix took my PoC and made a Guix package with it. WIP branch:

https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/zig.scm?h=wip-zig-bootstrap

I built it myself with guix, confirmed that it never involved zig1.wasm(.zst)?. So I will be putting my effort on hold until Hilton merges his; at which point it will be trivial for anyone to make zig1.wasm of master.

6 Likes

Just want to say that this was a great idea, thanks @motiejus for taking it on.

2 Likes

Here is a write-up: Zig Reproduced Without Binaries - Motiejus Jakštys Public Record

21 Likes

Pleased to hear @andrewrk hasn’t snuck in a supply chain attack while nobody was looking!

13 Likes