aboutsummaryrefslogtreecommitdiff
path: root/src/link/Wasm.zig
AgeCommit message (Collapse)Author
2021-11-27wasm-linker: Resolve relocationsLuuk de Gram
We now resolve relocations for globals, memory addresses and function indexes. Besides above, we now also emit imported functions correctly and create a corresponding undefined symbol for it, where as we create a defined symbol for all other cases. TODO: Make incrememental compilation work again with new linker infrastructure
2021-11-27wasm-linker: Upstream zwld into stage2Luuk de Gram
- Converts previous `DeclBlock` into `Atom`'s to also make them compatible when the rest of zlwd gets upstreamed and we can link with other object files. - Resolves function signatures and removes any duplicates, saving us a lot of potential bytes for larger projects. - We now create symbols for each decl of the respective type - We can now (but not implemented yet) perform proper relocations. - Having symbols and segment_info allows us to create an object file for wasm.
2021-11-24stage2: remove extra_lld_argsAndrew Kelley
This mechanism for sending arbitrary linker args to LLD has no place in the Zig frontend, because our goal is for the frontend to understand all the arguments and not treat linker args like a black box. For example we have self-hosted linking in addition to LLD, so we want to have the options make sense to both linking codepaths, not just the LLD one. Passing -O linker args will now result in a warning that the arg does nothing.
2021-11-21wasm: Linker - emit stack pointerLuuk de Gram
The self-hosted wasm linker now emits a mutable global. This entry represents the stack pointer, which has an initial value of offset table size + data size + stack size. Stack size can either be set by the user, or has the default of a single wasm page (64KiB).
2021-11-15Stage2: wasm - Implement the MIR pass (#10153)Luuk de Gram
* wasm: Move wasm's codegen to arch/wasm/CodeGen.zig * wasm: Define Wasm's Mir This declares the initial most-used instructions for wasm as well as the data that represents them. TODO: Add binary operand opcodes. By re-using the wasm opcode values, we can emit each opcode very easily by simply using `@enumToInt()`. However, this poses a possible problem: If we use all of wasm's opcodes, it leaves us no room to use synthetic opcodes such as debugging instructions. We could use reserved opcodes, but the wasm spec may use them at some point. TODO: Check if we should perhaps use a 16bit tag where the highest bits are used for synthetic opcodes. * wasm: Define basic Emit structure * wasm: Implement corresponding Emit functions for MIR * wasm: Initial lowering to MIR - This implements lowering to MIR from AIR for storing and loading of locals as well as emitting immediates. - Relocating function indexes has been simplified a lot as well as we no longer need to patch offsets and we write a relocatable value instead. - Locals are now emitted at the beginning of the function section entry meaning all offsets we generate are stable. * wasm: Lower all AIR instructions to MIR * wasm: Implement remaining MIR instructions * wasm: Fix function relocations * wasm: Get all tests working * wasm: Make `Data` 4 bytes instead of 8. - 64bit immediates are now stored in 2 seperate u32's. - 64bit floats are now stored in 2 seperate u32's. - `mem_arg` is now stored as a seperate payload in extra.
2021-11-10wasm: respect stack_size_override for build-obj and build-libAndrew Kelley
Related: #8633
2021-11-09stage2: add 4 new linker flags for WebAssemblyAndrew Kelley
--import-memory import memory from the environment --initial-memory=[bytes] initial size of the linear memory --max-memory=[bytes] maximum size of the linear memory --global-base=[addr] where to start to place global data See #8633
2021-09-24Spelling corrections (#9833)Josh Soref
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2021-09-24stage2: enable building freestanding libc with LLVM backendAndrew Kelley
* LLVM backend: respect `sub_path` just like the other stage2 backends do. * Compilation has some new logic to only emit work queue jobs for building stuff when it believes itself to be capable. The linker backends no longer have duplicate logic; instead they respect the optional bit on the respective asset.
2021-09-23stage2: LLVM backend: improved naming and exportingAndrew Kelley
Introduce an explicit decl_map for *Decl to LLVMValueRef. Doc comment reproduced here: Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function, but that has some downsides: * we have to compute the fully qualified name every time we want to do the lookup * for externally linked functions, the name is not fully qualified, but when a Decl goes from exported to not exported and vice-versa, we would use the wrong version of the name and incorrectly get function not found in the llvm module. * it works for functions not all globals. Therefore, this table keeps track of the mapping. Non-exported functions now use fully-qualified symbol names. `Module.Decl.getFullyQualifiedName` now returns a sentinel-terminated slice which is useful to pass to LLVMAddFunction. Instead of using aliases for all external symbols, now the LLVM backend takes advantage of LLVMSetValueName to rename functions that become exported. Aliases are still used for the second and remaining exports. freeDecl is now handled properly in the LLVM backend, deleting the LLVMValueRef corresponding to the Decl being deleted. The linker backends for ELF, COFF, Mach-O, and Wasm had to be updated to forward the freeDecl call to the LLVM backend.
2021-09-19Update all ensureCapacity calls to the relevant non-deprecated versionRyan Liptak
2021-08-24wasm: pass --export-dynamic to wasm-ld for WASI reactors. (#9605)Takeshi Yoneda
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2021-07-29stage2: more principled approach to comptime referencesAndrew Kelley
* AIR no longer has a `variables` array. Instead of the `varptr` instruction, Sema emits a constant with a `decl_ref`. * AIR no longer has a `ref` instruction. There is no longer any instruction that takes a value and returns a pointer to it. If this is desired, Sema must either create an anynomous Decl and return a constant `decl_ref`, or in the case of a runtime value, emit an `alloc` instruction, `store` the value to it, and then return the `alloc`. * The `ref_val` Value Tag is eliminated. `decl_ref` should be used instead. Also added is `eu_payload_ptr` which points to the payload of an error union, given an error union pointer. In general, Sema should avoid calling `analyzeRef` if it can be helped. For example in the case of field_val and elem_val, there should never be a reason to create a temporary (alloc or decl). Recent previous commits made progress along that front. There is a new abstraction in Sema, which looks like this: var anon_decl = try block.startAnonDecl(); defer anon_decl.deinit(); // here 'anon_decl.arena()` may be used const decl = try anon_decl.finish(ty, val); // decl is typically now used with `decl_ref`. This pattern is used to upgrade `ref_val` usages to `decl_ref` usages. Additional improvements: * Sema: fix source location resolution for calling convention expression. * Sema: properly report "unable to resolve comptime value" for loads of global variables. There is now a set of functions which can be called if the callee wants to obtain the Value even if the tag is `variable` (indicating comptime-known address but runtime-known value). * Sema: `coerce` resolves builtin types before checking equality. * Sema: fix `u1_type` missing from `addType`, making this type have a slightly more efficient representation in AIR. * LLVM backend: fix `genTypedValue` for tags `decl_ref` and `variable` to properly do an LLVMConstBitCast. * Remove unused parameter from `Value.toEnum`. After this commit, some test cases are no longer passing. This is due to the more principled approach to comptime references causing more anonymous decls to get sent to the linker for codegen. However, in all these cases the decls are not actually referenced by the runtime machine code. A future commit in this branch will implement garbage collection of decls so that unused decls do not get sent to the linker for codegen. This will make the tests go back to passing.
2021-07-26stage2: improvements towards `zig test`Andrew Kelley
* Add AIR instruction: struct_field_val - This is part of an effort to eliminate the AIR instruction `ref`. - It's implemented for C backend and LLVM backend so far. * Rename `resolvePossiblyUndefinedValue` to `resolveMaybeUndefVal` just to save some columns on long lines. * Sema: add `fieldVal` alongside `fieldPtr` (renamed from `namedFieldPtr`). This is part of an effort to eliminate the AIR instruction `ref`. The idea is to avoid unnecessary loads, stores, stack usage, and IR instructions, by paying a DRY cost. LLVM backend improvements: * internal linkage vs exported linkage is implemented, along with aliases. There is an issue with incremental updates due to missing LLVM API for deleting aliases; see the relevant comment in this commit. - `updateDeclExports` is hooked up to the LLVM backend now. * Fix usage of `Type.tag() == .noreturn` rather than calling `isNoReturn()`. * Properly mark global variables as mutable/constant. * Fix llvm type generation of function pointers * Fix codegen for calls of function pointers * Implement llvm type generation of error unions and error sets. * Implement AIR instructions: addwrap, subwrap, mul, mulwrap, div, bit_and, bool_and, bit_or, bool_or, xor, struct_field_ptr, struct_field_val, unwrap_errunion_err, add for floats, sub for floats. After this commit, `zig test` on a file with `test "example" {}` correctly generates and executes a test binary. However the `test_functions` slice is undefined and just happens to be going into the .bss section, causing the length to be 0. The next step towards `zig test` will be replacing the `test_functions` Decl Value with the set of test function pointers, before it is sent to linker/codegen.
2021-07-22support -fcompiler-rt in conjunction with build-objAndrew Kelley
When using `build-exe` or `build-lib -dynamic`, `-fcompiler-rt` means building compiler-rt into a static library and then linking it into the executable. When using `build-lib`, `-fcompiler-rt` means building compiler-rt into an object file and then adding it into the static archive. Before this commit, when using `build-obj`, zig would build compiler-rt into an object file, and then on ELF, use `lld -r` to merge it into the main object file. Other linker backends of LLD do not support `-r` to merge objects, so this failed with error messages for those targets. Now, `-fcompiler-rt` when used with `build-obj` acts as if the user puts `_ = @import("compiler_rt");` inside their root source file. The symbols of compiler-rt go into the same compilation unit as the root source file. This is hooked up for stage1 only for now. Once stage2 is capable of building compiler-rt, it should be hooked up there as well.
2021-07-22add -femit-llvm-bc CLI option and implement itAndrew Kelley
* Added doc comments for `std.Target.ObjectFormat` enum * `std.Target.oFileExt` is removed because it is incorrect for Plan-9 targets. Instead, use `std.Target.ObjectFormat.fileExt` and pass a CPU architecture. * Added `Compilation.Directory.joinZ` for when a null byte is desired. * Improvements to `Compilation.create` logic for computing `use_llvm` and reporting errors in contradictory flags. `-femit-llvm-ir` and `-femit-llvm-bc` will now imply `-fLLVM`. * Fix compilation when passing `.bc` files on the command line. * Improvements to the stage2 LLVM backend: - cleaned up error messages and error reporting. Properly bubble up some errors rather than dumping to stderr; others turn into panics. - properly call ZigLLVMCreateTargetMachine and ZigLLVMTargetMachineEmitToFile and implement calculation of the respective parameters (cpu features, code model, abi name, lto, tsan, etc). - LLVM module verification only runs in debug builds of the compiler - use LLVMDumpModule rather than printToString because in the case that we incorrectly pass a null pointer to LLVM it may crash during dumping the module and having it partially printed is helpful in this case. - support -femit-asm, -fno-emit-bin, -femit-llvm-ir, -femit-llvm-bc - Support LLVM backend when used with Mach-O and WASM linkers.
2021-07-20stage2: fix compile errors in LLVM backendAndrew Kelley
2021-07-20stage2: update LLVM backend to new AIR memory layoutAndrew Kelley
Also fix compile errors when not using -Dskip-non-native
2021-07-20Refactor entire wasm-backend to use new AIR memory layoutLuuk de Gram
2021-07-20Fix wasm-related compile errors:Luuk de Gram
- Update `fail()` to not require a `srcLoc`. This brings it in line with other backends, and we were always passing 'node_offset = 0', anyway. - Fix unused local due to change of architecture wrt function/decl generation. - Replace all old instructions to indexes within the function signatures.
2021-07-20stage2: Air and Liveness are passed ephemerallyAndrew Kelley
to the link infrastructure, instead of being stored with Module.Fn. This moves towards a strategy to make more efficient use of memory by not storing Air or Liveness data in the Fn struct, but computing it on demand, immediately sending it to the backend, and then immediately freeing it. Backends which want to defer codegen until flush() such as SPIR-V must move the Air/Liveness data upon `updateFunc` being called and keep track of that data in the backend implementation itself.
2021-07-02avoid calling into stage1 backend when AstGen failsAndrew Kelley
The motivation for this commit is that there exists source files which produce ast-check errors, but crash stage1 or otherwise trigger stage1 bugs. Previously to this commit, Zig would run AstGen, collect the compile errors, run stage1, report stage1 compile errors and exit if any, and then report AstGen compile errors. The main change in this commit is to report AstGen errors prior to invoking stage1, and in fact if any AstGen errors occur, do not invoke stage1 at all. This caused most of the compile error tests to fail due to things such as unused local variables and mismatched stage1/stage2 error messages. It was taking a long time to update the test cases one-by-one, so I took this opportunity to unify the stage1 and stage2 testing harness, specifically with regards to compile errors. In this way we can start keeping track of which tests pass for 1, 2, or both. `zig build test-compile-errors` no longer works; it is now integrated into `zig build test-stage2`. This is one step closer to executing compile error tests in parallel; in fact the ThreadPool object is already in scope. There are some cases where the stage1 compile errors were actually better; those are left failing in this commit, to be addressed in a follow-up commit. Other changes in this commit: * build.zig: improve support for -Dstage1 used with the test step. * AstGen: minor cosmetic changes to error messages. * stage2: add -fstage1 and -fno-stage1 flags. This now allows one to download a binary of the zig compiler and use the llvm backend of self-hosted. This was also needed for hooking up the test harness. However, I realized that stage1 calls exit() and also has memory leaks, so had to complicate the test harness by not using this flag after all and instead invoking as a child process. - These CLI flags will disappear once we start shipping the self-hosted compiler as the main compiler. Until then, they can be used to try out the work-in-progress stage2. * stage2: select the LLVM backend by default for release modes, as long as the target architecture is supported by LLVM. * test harness: support setting the optimize mode
2021-06-30Add support for WASI reactor in pure Zig-exe. (#9178)Takeshi Yoneda
* Add command line help for "-mexec-model" * Define WasmExecModel enum in std.builtin. * Drop the support for the old crt1.o in favor of crt1-command.o Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2021-06-21cleanups related to unused paramsAndrew Kelley
2021-06-21fix code broken from previous commitJacob G-W
2021-06-21std, src, doc, test: remove unused variablesJacob G-W
2021-06-15add various flags/options, and link libcxxabi.Takeshi Yoneda
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2021-06-14link/wasm: link libcxx.Takeshi Yoneda
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2021-06-10link: don't link system libs by the wasm linkerJakub Konka
The only allowed system libraries that we can link are libraries that are part of the sysroot such as libc or WASI emulated subcomponents. This is required as Wasm allows to defer symbol resolution until load time. For example, the following import in Zig ```zig extern "wasi_snapshot_preview1" fn proc_exit() void; ``` would normally result in appending `-lwasi_snapshot_preview1` flag to the linker line. However, for Wasm/WASI, the symbol is provided at load rather than link time, therefore, the linker should not be concerned with resolving the symbol. As a result, we should not consider system libs by the Wasm linker.
2021-06-09cc,wasi: use wasi_libc.CRTFile directly instead of WasiExecModelJakub Konka
2021-06-09cc,wasi: support WASI reactors via -mexec-model flag.Takeshi Yoneda
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2021-06-09cc,wasi: store CRTFile enum in wasi_emulated_libsJakub Konka
* then, in `link/Wasm.zig` map `CRTFile` to full emulated libs name * move logic for removing any mention of WASI snapshot `wasi_snapshot_preview1` from `Compilation.zig` into `link/Wasm.zig`
2021-06-09wasi: clean up linking logicJakub Konka
Do not try to link WASI libc or emulated subcomponents when not targeting WASI; e.g., when targeting `wasm32-freestanding`.
2021-06-09cc,wasi: build referenced-only emulated componentsJakub Konka
Move parsing of system libs into `main.zig` next to where we decide if we should link libC, and, if targeting WASI, if the specified libname equals one of the emulated components, save it on the side and remove it from the system libs. Then, build *only* those parts of WASI libc that were preserved in the previous step. This also fixes building of different crt1 bits needed to support reactors and commands.
2021-06-09cc,wasi: package emulations as static archivesJakub Konka
This replicates the expected behavior when using `clang` with upstream `wasi-libc` sysroot: linking emulated subcomponents such as process clocks or signals requires an explicit link flag in the compiler invocation, for example: ``` zig cc -target wasm32-wasi -lwasi-emulated-process-clocks main.c -o main.wasm ```
2021-06-03Breaking hash map changes for 0.8.0Martin Wickham
- hash/eql functions moved into a Context object - *Context functions pass an explicit context - *Adapted functions pass specialized keys and contexts - new getPtr() function returns a pointer to value - remove functions renamed to fetchRemove - new remove functions return bool - removeAssertDiscard deleted, use assert(remove(...)) instead - Keys and values are stored in separate arrays - Entry is now {*K, *V}, the new KV is {K, V} - BufSet/BufMap functions renamed to match other set/map types - fixed iterating-while-modifying bug in src/link/C.zig
2021-05-28wasm: Support error setsLuuk de Gram
2021-05-21wasm: fix object extension to standard .o from .o.wasmJakub Konka
This should offer more compatibility with external tooling when cross-compiling to wasm with zig.
2021-05-20cc,wasi: link compiled WASI libc with wasm-ldJakub Konka
2021-04-28stage2: semaDecl properly analyzes the decl blockAndrew Kelley
Also flattened out Decl TypedValue fields into ty, val, has_tv and add relevant fields to Decl for alignment and link section.
2021-04-09Fix memory cleanup and update unplugging to avoid infinite loopLuuk de Gram
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-08CleanupLuuk de Gram
2021-04-08Handle incremental compilation correctlyLuuk de Gram
2021-04-08Calculate data length to ensure correct pointer offsetsLuuk de Gram
2021-04-08Basic "Hello world" workingLuuk de Gram
2021-04-05stage2 wasm codegen: refactor to use wasm.buildOpcodegracefu
2021-03-02stage2: fixup some formatting errors ({x} -> {s})Timon Kruiper
These were missed in cd7c870bd81391dd97c5c75eb3910382ba7280a1
2021-02-24Merge remote-tracking branch 'origin/master' into ast-memory-layoutAndrew Kelley
2021-02-19astgen: fix remaining compile errorsAndrew Kelley
Now it builds and what remains in this branch is: * fix the stage2 compiler regressions from this branch * finish the rest of zig fmt test cases, get them passing * Merge in Vexu's translate-c AST branch & fix translate-c regressions