aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
AgeCommit message (Collapse)Author
2021-04-09stage2: fix case where public variables did not workjacob gw
2021-04-09Merge pull request #8470 from ziglang/stage2-startAndrew Kelley
stage2: blaze the trail for std lib integration
2021-04-09stage2: add error for private decls accessed from other filesjacob gw
2021-04-08stage2: fix the memory leaksAndrew Kelley
2021-04-08stage2: simplify Decl src_node fieldAndrew Kelley
Also fix "previous definition here" error notes to be correct.
2021-04-08stage2: blaze the trail for std lib integrationAndrew Kelley
This branch adds "builtin" and "std" to the import table when using the self-hosted backend. "builtin" gains one additional item: ``` pub const zig_is_stage2 = true; // false when using stage1 backend ``` This allows the std lib to do conditional compilation based on detecting which backend is being used. This will be removed from builtin as soon as self-hosted catches up to feature parity with stage1. Keep a sharp eye out - people are going to be tempted to abuse this. The general rule of thumb is do not use `builtin.zig_is_stage2`. However this commit breaks the rule so that we can gain limited start.zig support as we incrementally improve the self-hosted compiler. This commit also implements `fullyQualifiedNameHash` and related functionality, which effectively puts all Decls in their proper namespaces. `fullyQualifiedName` is not yet implemented. Stop printing "todo" log messages for test decls unless we are in test mode. Add "previous definition here" error notes for Decl name collisions. This commit does not bring us yet to a newly passing test case. Here's what I'm working towards: ```zig const std = @import("std"); export fn main() c_int { const a = std.fs.base64_alphabet[0]; return a - 'A'; } ``` Current output: ``` $ ./zig-cache/bin/zig build-exe test.zig test.zig:3:1: error: TODO implement more analyze elemptr zig-cache/lib/zig/std/start.zig:38:46: error: TODO implement structInitExpr ty ``` So the next steps are clear: * Sema: improve elemptr * AstGen: implement structInitExpr
2021-04-08Refactor link/wasm.zig to use offset tableLuuk de Gram
This refactor inserts an offset table into wasm's data section where each offset points to the actual data region. This means we can keep offset indexes consistant and do not have to perform any computer to determine where in the data section something like a static string exists. Instead during runtime it will load the data offset onto the stack.
2021-04-08Calculate data length to ensure correct pointer offsetsLuuk de Gram
2021-04-08stage2: revert to only has_decl and export ZIR supportAndrew Kelley
Reverting most of the code from the previous commits in this branch. Will pull in the code with modifications bit by bit.
2021-04-08stage2: fix bug where invalid ZIR was generatedTimon Kruiper
The following code caused an assertion to be hit: ``` pub fn main() void { var e: anyerror!c_int = error.Foo; const i = e catch 69; assert(69 - i == 0); } ```
2021-04-08stage2: add support for start.zigTimon Kruiper
This adds a simplified start2.zig that the current stage2 compiler is able to generate code for.
2021-04-08stage2: fix bug in ZIR gen of global comptime blockTimon Kruiper
A global comptime block did not end with a break_inline instruction which caused an assertion to be hit.
2021-04-07stage2: fix switch validation of handling all enum valuesAndrew Kelley
There were several problems, all fixed: * AstGen was storing field names as references to the original source code bytes. However, that data would be destroyed when the source file is updated. Now, it correctly stores the field names in the Decl arena for the enum. The same fix applies to error set field names. * Sema was missing a memset inside `analyzeSwitch`, leaving the "seen enum fields" array with undefined memory. Now that they are all properly set to null, the validation works. * Moved the "enum declared here" note to the end. It looked weird interrupting the notes for which enum values were missing.
2021-04-07stage2: fix incremental compilation handling of parse errorsAndrew Kelley
Before, incremental compilation would crash when trying to emit compile errors for the update after introducing a parse error. Parse errors are handled by not invalidating any existing semantic analysis. However, only the parse error must be reported, with all the other errors suppressed. Once the parse error is fixed, the new file can be treated as an update to the previously-succeeded update.
2021-04-07stage2: fix incremental compilation Decl deletion logicAndrew Kelley
* `analyzeContainer` now has an `outdated_decls` set as well as `deleted_decls`. Instead of queuing up outdated Decls for re-analysis right away, they are added to this new set. When processing the `deleted_decls` set, we remove deleted Decls from the `outdated_decls` set, to avoid deleted Decl pointers from being in the work_queue. Only after processing the deleted decls do we add analyze_decl work items to the queue. * Module.deletion_set is now an `AutoArrayHashMap` rather than `ArrayList`. `declareDeclDependency` will now remove a Decl from it as appropriate. When processing the `deletion_set` in `Compilation.performAllTheWork`, it now assumes all Decl in the set are to be deleted. * Fix crash when handling parse errors. Currently we unload the `ast.Tree` if any parse errors occur. Previously the code emitted a LazySrcLoc pointing to a token index, but then when we try to resolve the token index to a byte offset to create a compile error message, the ast.Tree` would be unloaded. Now we use `LazySrcLoc.byte_abs` instead of `token_abs` so the error message can be created even with the `ast.Tree` unloaded. Together, these changes solve a crash that happened with incremental compilation when Decls were added and removed in some combinations.
2021-04-07Sema: DRY up enum field analysis and add "declared here" notesAndrew Kelley
2021-04-06stage2: implement simple enumsAndrew Kelley
A simple enum is an enum which has an automatic integer tag type, all tag values automatically assigned, and no top level declarations. Such enums are created directly in AstGen and shared by all the generic/comptime instantiations of the surrounding ZIR code. This commit implements, but does not yet add any test cases for, simple enums. A full enum is an enum for which any of the above conditions are not true. Full enums are created in Sema, and therefore will create a unique type per generic/comptime instantiation. This commit does not implement full enums. However the `enum_decl_nonexhaustive` ZIR instruction is added and the respective Type functions are filled out. This commit makes an improvement to ZIR code, removing the decls array and removing the decl_map from AstGen. Instead, decl_ref and decl_val ZIR instructions index into the `owner_decl.dependencies` ArrayHashMap. We already need this dependencies array for incremental compilation purposes, and so repurposing it to also use it for ZIR decl indexes makes for efficient memory usage. Similarly, this commit fixes up incorrect memory management by removing the `const` ZIR instruction. The two places it was used stored memory in the AstGen arena, which may get freed after Sema. Now it properly sets up a new anonymous Decl for error sets and uses a normal decl_val instruction. The other usage of `const` ZIR instruction was float literals. These are now changed to use `float` ZIR instruction when the value fits inside `zir.Inst.Data` and `float128` otherwise. AstGen + Sema: implement int_to_enum and enum_to_int. No tests yet; I expect to have to make some fixes before they will pass tests. Will do that in the branch before merging. AstGen: fix struct astgen incorrectly counting decls as fields. Type/Value: give up on trying to exhaustively list every tag all the time. This makes the file more manageable. Also found a bug with i128/u128 this way, since the name of the function was more obvious when looking at the tag values. Type: implement abiAlignment and abiSize for structs. This will need to get more sophisticated at some point, but for now it is progress. Value: add new `enum_field_index` tag. Value: add hash_u32, needed when using ArrayHashMap.
2021-04-02stage2: Sema: implement validate_struct_init_ptrAndrew Kelley
2021-04-02stage2: progress towards basic structsAndrew Kelley
Introduce `ResultLoc.none_or_ref` which is used by field access expressions to avoid unnecessary loads when the field access itself will do the load. This turns: ```zig p.y - p.x - p.x ``` from ```zir %14 = load(%4) node_offset:8:12 %15 = field_val(%14, "y") node_offset:8:13 %16 = load(%4) node_offset:8:18 %17 = field_val(%16, "x") node_offset:8:19 %18 = sub(%15, %17) node_offset:8:16 %19 = load(%4) node_offset:8:24 %20 = field_val(%19, "x") node_offset:8:25 ``` to ```zir %14 = field_val(%4, "y") node_offset:8:13 %15 = field_val(%4, "x") node_offset:8:19 %16 = sub(%14, %15) node_offset:8:16 %17 = field_val(%4, "x") node_offset:8:25 ``` Much more compact. This requires `Sema.zirFieldVal` to support both pointers and non-pointers. C backend: Implement typedefs for struct types, as well as the following TZIR instructions: * mul * mulwrap * addwrap * subwrap * ref * struct_field_ptr Note that add, addwrap, sub, subwrap, mul, mulwrap instructions are all incorrect currently and need to be updated to properly handle wrapping and non wrapping for signed and unsigned. C backend: change indentation delta to 1, to make the output smaller and to process fewer bytes. I promise I will add a test case as soon as I fix those warnings that are being printed for my test case.
2021-04-01stage2: implement structs in the frontendAndrew Kelley
New ZIR instructions: * struct_decl_packed * struct_decl_extern New TZIR instruction: struct_field_ptr Introduce `Module.Struct`. It uses `Value` to store default values and abi alignments. Implemented Sema.analyzeStructFieldPtr and zirStructDecl. Some stuff I changed from `@panic("TODO")` to `log.warn("TODO")`. It's becoming more clear that we need the lazy value mechanism soon; Type is becoming unruly, and some of these functions have too much logic given that they don't have any context for memory management or error reporting.
2021-04-01stage2: implement struct init syntax with ptr result locAndrew Kelley
2021-03-31stage2: finish implementation of LazySrcLocAndrew Kelley
2021-03-31stage2: finish source location reworkings in the branchAndrew Kelley
* remove the LazySrcLoc.todo tag * finish updating Sema and AstGen, remove the last of the `@panic("TODO")`.
2021-03-31astgen: improved handling of coercionAndrew Kelley
GenZir struct now has rl_ty_inst field which tracks the result location type (if any) a block expects all of its results to be coerced to. Remove a redundant coercion on const local initialization with a specified type. Switch expressions, during elision of store_to_block_ptr instructions, now re-purpose them to be type coercion when the block has a type in the result location.
2021-03-29Sema: implement switch expressionsAndrew Kelley
The logic for putting ranges into the else prong is moved from AstGen to Sema. However, logic to emit multi-items the same as single-items cannot be done until TZIR supports mapping multiple items to the same block of code. This will be simple to represent when we do the upcoming TZIR memory layout changes. Not yet implemented in this commit is the validation of duplicate values. The trick is going to be emitting error messages with accurate source locations, without adding extra source nodes to the ZIR switch instruction. This will be done by computing the respective AST node based on the switch node (which we do have available), only when a compile error occurs and we need to know the source location to attach the message to.
2021-03-28stage2: guidance on how to implement switch expressionsAndrew Kelley
Here's what I think the ZIR should be. AstGen is not yet implemented to match this, and the main implementation of analyzeSwitch in Sema is not yet implemented to match it either. Here are some example byte size reductions from master branch, with the ZIR memory layout from this commit: ``` switch (foo) { a => 1, b => 2, c => 3, d => 4, } ``` 184 bytes (master) => 40 bytes (this branch) ``` switch (foo) { a, b => 1, c..d, e, f => 2, g => 3, else => 4, } ``` 240 bytes (master) => 80 bytes (this branch)
2021-03-28stage2: fix error setsAndrew Kelley
2021-03-28stage2: implement sema for @errorToInt and @intToErrorjacob gw
2021-03-28AstGen: pass *GenZir as the first arg, not *ModuleIsaac Freund
This avoids the unnecessary scope.getGenZir() virtual call for both convenience and performance.
2021-03-28AstGen: scope result location related functionsIsaac Freund
2021-03-28stage2: rename WipZirCode => AstGen, astgen.zig => AstGen.zigIsaac Freund
2021-03-26stage2: implement bitwise expr and error literalsAndrew Kelley
2021-03-26stage2: implement source location: .node_offset_var_decl_tyAndrew Kelley
2021-03-25stage2: improve source locations of Decl accessAndrew Kelley
* zir.Code: introduce a decls array. This is so that `decl_val` and `decl_ref` instructions can refer to a Decl with a u32 and therefore they can also store a source location. This is needed for proper compile error reporting. * astgen uses a hash map to avoid redundantly adding a Decl to the decls array. * fixed reporting "instruction illegal outside function body" instead of the desired message "unable to resolve comptime value". * astgen skips emitting dbg_stmt instructions in comptime scopes. * astgen has some logic to avoid adding unnecessary type coercion instructions for common values.
2021-03-25stage2: implement inline whileAndrew Kelley
Introduce "inline" variants of ZIR tags: * block => block_inline * repeat => repeat_inline * break => break_inline * condbr => condbr_inline The inline variants perform control flow at compile-time, and they utilize the return value of `Sema.analyzeBody`. `analyzeBody` now returns an Index, not a Ref, which is the ZIR index of a break instruction. This effectively communicates both the intended break target block as well as the operand, allowing parent blocks to find out whether they, in turn, should return the break instruction up the call stack, or accept the operand as the block's result and continue analyzing instructions in the block. Additionally: * removed the deprecated ZIR tag `block_comptime`. * removed `break_void_node` so that all break instructions use the same Data. * zir.Code: remove the `root_start` and `root_len` fields. There is now implied to be a block at index 0 for the root body. This is so that `break_inline` has something to point at and we no longer need the special instruction `break_flat`. * implement source location byteOffset() for .node_offset_if_cond .node_offset_for_cond is probably redundant and can be deleted. We don't have `comptime var` supported yet, so this commit adds a test that at least makes sure the condition is required to be comptime known for `inline while`.
2021-03-24stage2: clean up break / noreturn astgenAndrew Kelley
* Module.addBreak and addBreakVoid return zir.Inst.Index not Ref because Index is the simpler type and we never need a Ref for these. * astgen: make noreturn stuff return the unreachable_value and avoid unnecessary calls to rvalue() * breakExpr: avoid unnecessary access into the tokens array * breakExpr: fix incorrect `@intCast` (previously this unsafely casted an Index to a Ref)
2021-03-24astgen: implement breaking from a blockTimon Kruiper
2021-03-24stage2: fix memory leak when updating a functionAndrew Kelley
2021-03-24stage2: further cleanups regarding zir.Inst.RefAndrew Kelley
* Introduce helper functions on Module.WipZirCode and zir.Code * Move some logic around * re-introduce ref_start_index * prefer usize for local variables + `@intCast` at the end. Empirically this is easier to optimize. * Avoid using mem.{bytesAsSlice,sliceAsBytes} because it incurs an unnecessary multiplication/division which may cause problems for the optimizer. * Use a regular enum, not packed, for `Ref`. Memory layout is guaranteed for enums which specify their tag type. Packed enums have ABI alignment of 1 byte which is too small.
2021-03-24stage2: make zir.Inst.Ref a non-exhaustive enumIsaac Freund
This provides us greatly increased type safety and prevents the common mistake of using a zir.Inst.Ref where a zir.Inst.Index was expected or vice-versa. It also increases the ergonomics of using the typed values which can be directly referenced with a Ref over the previous zir.Const approach. The main pain point is casting between a []Ref and []u32, which could be alleviated in the future with a new std.mem function.
2021-03-23stage2: comment out failing test cases; implement more thingsAndrew Kelley
* comment out the failing stage2 test cases (so that we can uncomment the ones that are newly passing with further commits) * Sema: implement negate, negatewrap * astgen: implement field access, multiline string literals, and character literals * Module: when resolving an AST node into a byte offset, use the main_tokens array, not the firstToken function
2021-03-23stage2: fix while loopsAndrew Kelley
also start to form a plan for how inline while loops will work
2021-03-23astgen: fixups regarding var decls and rl_ptrAndrew Kelley
2021-03-23stage2: implement inttype ZIRAndrew Kelley
also add i128 and u128 to const inst list
2021-03-23stage2: fix comptimeExpr and comptime function callsAndrew Kelley
2021-03-23stage2: add helper functions to clean up astgen Ref/IndexAndrew Kelley
2021-03-23stage2: fix two return types to be Ref not IndexIsaac Freund
We currently have no type safety between zir.Inst.Ref, zir.Inst.Index, and plain u32s.
2021-03-22stage2: fix `if` expressionsAndrew Kelley
2021-03-22astgen: improve the ensure_unused_result elisionAndrew Kelley
2021-03-22stage2: Sema improvements and boolean logic astgenAndrew Kelley
* add `Module.setBlockBody` and related functions * redo astgen for `and` and `or` to use fewer ZIR instructions and require less processing for comptime known values * Sema: rework `analyzeBody` function. See the new doc comments in this commit. Divides ZIR instructions up into 3 categories: - always noreturn - never noreturn - sometimes noreturn