| ... | @@ -19,6 +19,7 @@ | ... | @@ -19,6 +19,7 @@ |
| 19 | #include "target.hpp" | 19 | #include "target.hpp" |
| 20 | #include "util.hpp" | 20 | #include "util.hpp" |
| 21 | #include "zig_llvm.h" | 21 | #include "zig_llvm.h" |
| | 22 | #include "blake2.h" |
| 22 | | 23 | |
| 23 | #include <stdio.h> | 24 | #include <stdio.h> |
| 24 | #include <errno.h> | 25 | #include <errno.h> |
| ... | @@ -183,10 +184,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out | ... | @@ -183,10 +184,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out |
| 183 | return g; | 184 | return g; |
| 184 | } | 185 | } |
| 185 | | 186 | |
| 186 | void codegen_destroy(CodeGen *codegen) { | | |
| 187 | LLVMDisposeTargetMachine(codegen->target_machine); | | |
| 188 | } | | |
| 189 | | | |
| 190 | void codegen_set_output_h_path(CodeGen *g, Buf *h_path) { | 187 | void codegen_set_output_h_path(CodeGen *g, Buf *h_path) { |
| 191 | g->out_h_path = h_path; | 188 | g->out_h_path = h_path; |
| 192 | } | 189 | } |
| ... | @@ -7112,23 +7109,30 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { | ... | @@ -7112,23 +7109,30 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { |
| 7112 | g->test_runner_import = add_special_code(g, g->test_runner_package, "test_runner.zig"); | 7109 | g->test_runner_import = add_special_code(g, g->test_runner_package, "test_runner.zig"); |
| 7113 | } | 7110 | } |
| 7114 | | 7111 | |
| 7115 | static void gen_root_source(CodeGen *g) { | 7112 | static Buf *get_resolved_root_src_path(CodeGen *g) { |
| | 7113 | // TODO memoize |
| 7116 | if (buf_len(&g->root_package->root_src_path) == 0) | 7114 | if (buf_len(&g->root_package->root_src_path) == 0) |
| 7117 | return; | 7115 | return nullptr; |
| 7118 | | | |
| 7119 | codegen_add_time_event(g, "Semantic Analysis"); | | |
| 7120 | | 7116 | |
| 7121 | Buf *rel_full_path = buf_alloc(); | 7117 | Buf rel_full_path = BUF_INIT; |
| 7122 | os_path_join(&g->root_package->root_src_dir, &g->root_package->root_src_path, rel_full_path); | 7118 | os_path_join(&g->root_package->root_src_dir, &g->root_package->root_src_path, &rel_full_path); |
| 7123 | | 7119 | |
| 7124 | Buf *resolved_path = buf_alloc(); | 7120 | Buf *resolved_path = buf_alloc(); |
| 7125 | Buf *resolve_paths[] = {rel_full_path}; | 7121 | Buf *resolve_paths[] = {&rel_full_path}; |
| 7126 | *resolved_path = os_path_resolve(resolve_paths, 1); | 7122 | *resolved_path = os_path_resolve(resolve_paths, 1); |
| 7127 | | 7123 | |
| | 7124 | return resolved_path; |
| | 7125 | } |
| | 7126 | |
| | 7127 | static void gen_root_source(CodeGen *g) { |
| | 7128 | Buf *resolved_path = get_resolved_root_src_path(g); |
| | 7129 | if (resolved_path == nullptr) |
| | 7130 | return; |
| | 7131 | |
| 7128 | Buf *source_code = buf_alloc(); | 7132 | Buf *source_code = buf_alloc(); |
| 7129 | int err; | 7133 | int err; |
| 7130 | if ((err = os_fetch_file_path(rel_full_path, source_code, true))) { | 7134 | if ((err = os_fetch_file_path(resolved_path, source_code, true))) { |
| 7131 | fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(rel_full_path), err_str(err)); | 7135 | fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(resolved_path), err_str(err)); |
| 7132 | exit(1); | 7136 | exit(1); |
| 7133 | } | 7137 | } |
| 7134 | | 7138 | |
| ... | @@ -7671,10 +7675,155 @@ void codegen_add_time_event(CodeGen *g, const char *name) { | ... | @@ -7671,10 +7675,155 @@ void codegen_add_time_event(CodeGen *g, const char *name) { |
| 7671 | g->timing_events.append({os_get_time(), name}); | 7675 | g->timing_events.append({os_get_time(), name}); |
| 7672 | } | 7676 | } |
| 7673 | | 7677 | |
| | 7678 | static void add_cache_str(blake2b_state *blake, const char *ptr) { |
| | 7679 | assert(ptr != nullptr); |
| | 7680 | // + 1 to include the null byte |
| | 7681 | blake2b_update(blake, ptr, strlen(ptr) + 1); |
| | 7682 | } |
| | 7683 | |
| | 7684 | static void add_cache_int(blake2b_state *blake, int x) { |
| | 7685 | // + 1 to include the null byte |
| | 7686 | uint8_t buf[sizeof(int) + 1]; |
| | 7687 | memcpy(buf, &x, sizeof(int)); |
| | 7688 | buf[sizeof(int)] = 0; |
| | 7689 | blake2b_update(blake, buf, sizeof(int) + 1); |
| | 7690 | } |
| | 7691 | |
| | 7692 | static void add_cache_buf(blake2b_state *blake, Buf *buf) { |
| | 7693 | assert(buf != nullptr); |
| | 7694 | // + 1 to include the null byte |
| | 7695 | blake2b_update(blake, buf_ptr(buf), buf_len(buf) + 1); |
| | 7696 | } |
| | 7697 | |
| | 7698 | static void add_cache_buf_opt(blake2b_state *blake, Buf *buf) { |
| | 7699 | if (buf == nullptr) { |
| | 7700 | add_cache_str(blake, ""); |
| | 7701 | add_cache_str(blake, ""); |
| | 7702 | } else { |
| | 7703 | add_cache_buf(blake, buf); |
| | 7704 | } |
| | 7705 | } |
| | 7706 | |
| | 7707 | static void add_cache_list_of_link_lib(blake2b_state *blake, LinkLib **ptr, size_t len) { |
| | 7708 | for (size_t i = 0; i < len; i += 1) { |
| | 7709 | LinkLib *lib = ptr[i]; |
| | 7710 | if (lib->provided_explicitly) { |
| | 7711 | add_cache_buf(blake, lib->name); |
| | 7712 | } |
| | 7713 | } |
| | 7714 | add_cache_str(blake, ""); |
| | 7715 | } |
| | 7716 | |
| | 7717 | static void add_cache_list_of_buf(blake2b_state *blake, Buf **ptr, size_t len) { |
| | 7718 | for (size_t i = 0; i < len; i += 1) { |
| | 7719 | Buf *buf = ptr[i]; |
| | 7720 | add_cache_buf(blake, buf); |
| | 7721 | } |
| | 7722 | add_cache_str(blake, ""); |
| | 7723 | } |
| | 7724 | |
| | 7725 | //static void add_cache_file(CodeGen *g, blake2b_state *blake, Buf *resolved_path) { |
| | 7726 | // assert(file_name != nullptr); |
| | 7727 | // g->cache_files.append(resolved_path); |
| | 7728 | //} |
| | 7729 | // |
| | 7730 | //static void add_cache_file_opt(CodeGen *g, blake2b_state *blake, Buf *resolved_path) { |
| | 7731 | // if (resolved_path == nullptr) { |
| | 7732 | // add_cache_str(blake, ""); |
| | 7733 | // add_cache_str(blake, ""); |
| | 7734 | // } else { |
| | 7735 | // add_cache_file(g, blake, resolved_path); |
| | 7736 | // } |
| | 7737 | //} |
| | 7738 | |
| | 7739 | // Ported from std/base64.zig |
| | 7740 | static uint8_t base64_fs_alphabet[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"; |
| | 7741 | static void base64_encode(Slice<uint8_t> dest, Slice<uint8_t> source) { |
| | 7742 | size_t dest_len = ((source.len + 2) / 3) * 4; |
| | 7743 | assert(dest.len == dest_len); |
| | 7744 | |
| | 7745 | size_t i = 0; |
| | 7746 | size_t out_index = 0; |
| | 7747 | for (; i + 2 < source.len; i += 3) { |
| | 7748 | dest.ptr[out_index] = base64_fs_alphabet[(source.ptr[i] >> 2) & 0x3f]; |
| | 7749 | out_index += 1; |
| | 7750 | |
| | 7751 | dest.ptr[out_index] = base64_fs_alphabet[((source.ptr[i] & 0x3) << 4) | ((source.ptr[i + 1] & 0xf0) >> 4)]; |
| | 7752 | out_index += 1; |
| | 7753 | |
| | 7754 | dest.ptr[out_index] = base64_fs_alphabet[((source.ptr[i + 1] & 0xf) << 2) | ((source.ptr[i + 2] & 0xc0) >> 6)]; |
| | 7755 | out_index += 1; |
| | 7756 | |
| | 7757 | dest.ptr[out_index] = base64_fs_alphabet[source.ptr[i + 2] & 0x3f]; |
| | 7758 | out_index += 1; |
| | 7759 | } |
| | 7760 | |
| | 7761 | // Assert that we never need pad characters. |
| | 7762 | assert(i == source.len); |
| | 7763 | //if (i < source.len) { |
| | 7764 | // dest.ptr[out_index] = base64_fs_alphabet[(source.ptr[i] >> 2) & 0x3f]; |
| | 7765 | // out_index += 1; |
| | 7766 | |
| | 7767 | // if (i + 1 == source.len) { |
| | 7768 | // dest.ptr[out_index] = base64_fs_alphabet[(source.ptr[i] & 0x3) << 4]; |
| | 7769 | // out_index += 1; |
| | 7770 | |
| | 7771 | // dest.ptr[out_index] = encoder.pad_char; |
| | 7772 | // out_index += 1; |
| | 7773 | // } else { |
| | 7774 | // dest.ptr[out_index] = base64_fs_alphabet[((source.ptr[i] & 0x3) << 4) | ((source.ptr[i + 1] & 0xf0) >> 4)]; |
| | 7775 | // out_index += 1; |
| | 7776 | |
| | 7777 | // dest.ptr[out_index] = base64_fs_alphabet[(source.ptr[i + 1] & 0xf) << 2]; |
| | 7778 | // out_index += 1; |
| | 7779 | // } |
| | 7780 | |
| | 7781 | // dest.ptr[out_index] = encoder.pad_char; |
| | 7782 | // out_index += 1; |
| | 7783 | //} |
| | 7784 | } |
| | 7785 | |
| | 7786 | // Called before init() |
| | 7787 | static bool build_with_cache(CodeGen *g) { |
| | 7788 | blake2b_state blake; |
| | 7789 | int rc = blake2b_init(&blake, 48); |
| | 7790 | assert(rc == 0); |
| | 7791 | |
| | 7792 | // TODO zig exe & dynamic libraries |
| | 7793 | |
| | 7794 | add_cache_buf(&blake, g->root_out_name); |
| | 7795 | add_cache_buf_opt(&blake, get_resolved_root_src_path(g)); // Root source file |
| | 7796 | add_cache_list_of_link_lib(&blake, g->link_libs_list.items, g->link_libs_list.length); |
| | 7797 | add_cache_list_of_buf(&blake, g->darwin_frameworks.items, g->darwin_frameworks.length); |
| | 7798 | add_cache_list_of_buf(&blake, g->rpath_list.items, g->rpath_list.length); |
| | 7799 | add_cache_int(&blake, g->emit_file_type); |
| | 7800 | add_cache_int(&blake, g->build_mode); |
| | 7801 | add_cache_int(&blake, g->out_type); |
| | 7802 | // TODO the rest of the struct CodeGen fields |
| | 7803 | |
| | 7804 | uint8_t bin_digest[48]; |
| | 7805 | rc = blake2b_final(&blake, bin_digest, 48); |
| | 7806 | assert(rc == 0); |
| | 7807 | |
| | 7808 | Buf b64_digest = BUF_INIT; |
| | 7809 | buf_resize(&b64_digest, 64); |
| | 7810 | base64_encode(buf_to_slice(&b64_digest), {bin_digest, 48}); |
| | 7811 | |
| | 7812 | fprintf(stderr, "input params hash: %s\n", buf_ptr(&b64_digest)); |
| | 7813 | // TODO next look for a manifest file that has all the files from the input parameters |
| | 7814 | // use that to construct the real hash, which looks up the output directory and another manifest file |
| | 7815 | |
| | 7816 | return false; |
| | 7817 | } |
| | 7818 | |
| 7674 | void codegen_build(CodeGen *g) { | 7819 | void codegen_build(CodeGen *g) { |
| 7675 | assert(g->out_type != OutTypeUnknown); | 7820 | assert(g->out_type != OutTypeUnknown); |
| | 7821 | if (build_with_cache(g)) |
| | 7822 | return; |
| 7676 | init(g); | 7823 | init(g); |
| 7677 | | 7824 | |
| | 7825 | codegen_add_time_event(g, "Semantic Analysis"); |
| | 7826 | |
| 7678 | gen_global_asm(g); | 7827 | gen_global_asm(g); |
| 7679 | gen_root_source(g); | 7828 | gen_root_source(g); |
| 7680 | do_code_gen(g); | 7829 | do_code_gen(g); |