| author | |
| committer | |
| log | 3268276b58d8b65cb295b738d7c14174005bd84e |
| tree | c52b5524962c7ab37129318b5aba31b9d83820f6 |
| parent | 465e75bc5a41aa899b673c0a3ff59d6da871fbe6 |
this makes it so that you can send the same string literal
as a comptime slice and get the same type6 files changed, 31 insertions(+), 5 deletions(-)
src/all_types.hpp+1| ... | @@ -1421,6 +1421,7 @@ struct CodeGen { | ... | @@ -1421,6 +1421,7 @@ struct CodeGen { |
| 1421 | HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table; | 1421 | HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table; |
| 1422 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names; | 1422 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names; |
| 1423 | HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes; | 1423 | HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes; |
| 1424 | HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> string_literals_table; | ||
| 1424 | 1425 | ||
| 1425 | 1426 | ||
| 1426 | ZigList<ImportTableEntry *> import_queue; | 1427 | ZigList<ImportTableEntry *> import_queue; |
src/analyze.cpp+8| ... | @@ -4370,6 +4370,12 @@ bool type_requires_comptime(TypeTableEntry *type_entry) { | ... | @@ -4370,6 +4370,12 @@ bool type_requires_comptime(TypeTableEntry *type_entry) { |
| 4370 | } | 4370 | } |
| 4371 | 4371 | ||
| 4372 | void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { | 4372 | void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { |
| 4373 | auto entry = g->string_literals_table.maybe_get(str); | ||
| 4374 | if (entry != nullptr) { | ||
| 4375 | *const_val = *entry->value; | ||
| 4376 | return; | ||
| 4377 | } | ||
| 4378 | |||
| 4373 | const_val->special = ConstValSpecialStatic; | 4379 | const_val->special = ConstValSpecialStatic; |
| 4374 | const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str)); | 4380 | const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str)); |
| 4375 | const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str)); | 4381 | const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str)); |
| ... | @@ -4380,6 +4386,8 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { | ... | @@ -4380,6 +4386,8 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { |
| 4380 | this_char->type = g->builtin_types.entry_u8; | 4386 | this_char->type = g->builtin_types.entry_u8; |
| 4381 | bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]); | 4387 | bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]); |
| 4382 | } | 4388 | } |
| 4389 | |||
| 4390 | g->string_literals_table.put(str, const_val); | ||
| 4383 | } | 4391 | } |
| 4384 | 4392 | ||
| 4385 | ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { | 4393 | ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { |
src/buffer.cpp+4-1| ... | @@ -67,9 +67,12 @@ bool buf_eql_buf(Buf *buf, Buf *other) { | ... | @@ -67,9 +67,12 @@ bool buf_eql_buf(Buf *buf, Buf *other) { |
| 67 | 67 | ||
| 68 | uint32_t buf_hash(Buf *buf) { | 68 | uint32_t buf_hash(Buf *buf) { |
| 69 | assert(buf->list.length); | 69 | assert(buf->list.length); |
| 70 | size_t interval = buf->list.length / 256; | ||
| 71 | if (interval == 0) | ||
| 72 | interval = 1; | ||
| 70 | // FNV 32-bit hash | 73 | // FNV 32-bit hash |
| 71 | uint32_t h = 2166136261; | 74 | uint32_t h = 2166136261; |
| 72 | for (size_t i = 0; i < buf_len(buf); i += 1) { | 75 | for (size_t i = 0; i < buf_len(buf); i += interval) { |
| 73 | h = h ^ ((uint8_t)buf->list.at(i)); | 76 | h = h ^ ((uint8_t)buf->list.at(i)); |
| 74 | h = h * 16777619; | 77 | h = h * 16777619; |
| 75 | } | 78 | } |
src/codegen.cpp+1| ... | @@ -87,6 +87,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out | ... | @@ -87,6 +87,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out |
| 87 | g->memoized_fn_eval_table.init(16); | 87 | g->memoized_fn_eval_table.init(16); |
| 88 | g->exported_symbol_names.init(8); | 88 | g->exported_symbol_names.init(8); |
| 89 | g->external_prototypes.init(8); | 89 | g->external_prototypes.init(8); |
| 90 | g->string_literals_table.init(16); | ||
| 90 | g->is_test_build = false; | 91 | g->is_test_build = false; |
| 91 | g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib); | 92 | g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib); |
| 92 | buf_resize(&g->global_asm, 0); | 93 | buf_resize(&g->global_asm, 0); |
src/ir.cpp+4-4| ... | @@ -13224,9 +13224,9 @@ static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstr | ... | @@ -13224,9 +13224,9 @@ static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstr |
| 13224 | os_path_resolve(&source_dir_path, rel_file_path, &file_path); | 13224 | os_path_resolve(&source_dir_path, rel_file_path, &file_path); |
| 13225 | 13225 | ||
| 13226 | // load from file system into const expr | 13226 | // load from file system into const expr |
| 13227 | Buf file_contents = BUF_INIT; | 13227 | Buf *file_contents = buf_alloc(); |
| 13228 | int err; | 13228 | int err; |
| 13229 | if ((err = os_fetch_file_path(&file_path, &file_contents))) { | 13229 | if ((err = os_fetch_file_path(&file_path, file_contents))) { |
| 13230 | if (err == ErrorFileNotFound) { | 13230 | if (err == ErrorFileNotFound) { |
| 13231 | ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(&file_path))); | 13231 | ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(&file_path))); |
| 13232 | return ira->codegen->builtin_types.entry_invalid; | 13232 | return ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -13240,9 +13240,9 @@ static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstr | ... | @@ -13240,9 +13240,9 @@ static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstr |
| 13240 | // we'll have to invalidate the cache | 13240 | // we'll have to invalidate the cache |
| 13241 | 13241 | ||
| 13242 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 13242 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 13243 | init_const_str_lit(ira->codegen, out_val, &file_contents); | 13243 | init_const_str_lit(ira->codegen, out_val, file_contents); |
| 13244 | 13244 | ||
| 13245 | return get_array_type(ira->codegen, ira->codegen->builtin_types.entry_u8, buf_len(&file_contents)); | 13245 | return get_array_type(ira->codegen, ira->codegen->builtin_types.entry_u8, buf_len(file_contents)); |
| 13246 | } | 13246 | } |
| 13247 | 13247 | ||
| 13248 | static TypeTableEntry *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchg *instruction) { | 13248 | static TypeTableEntry *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchg *instruction) { |
test/cases/eval.zig+13| ... | @@ -375,3 +375,16 @@ test "f128 at compile time is lossy" { | ... | @@ -375,3 +375,16 @@ test "f128 at compile time is lossy" { |
| 375 | 375 | ||
| 376 | // TODO need a better implementation of bigfloat_init_bigint | 376 | // TODO need a better implementation of bigfloat_init_bigint |
| 377 | // assert(f128(1 << 113) == 10384593717069655257060992658440192); | 377 | // assert(f128(1 << 113) == 10384593717069655257060992658440192); |
| 378 | |||
| 379 | pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) -> type { | ||
| 380 | return struct { | ||
| 381 | pub const Node = struct { }; | ||
| 382 | }; | ||
| 383 | } | ||
| 384 | |||
| 385 | test "string literal used as comptime slice is memoized" { | ||
| 386 | const a = "link"; | ||
| 387 | const b = "link"; | ||
| 388 | comptime assert(TypeWithCompTimeSlice(a).Node == TypeWithCompTimeSlice(b).Node); | ||
| 389 | comptime assert(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node); | ||
| 390 | } |