|
@@ -85,6 +85,7 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) {
|
|
|
string_map_init(&m->members);
|
|
|
string_map_init(&m->procedures);
|
|
|
string_map_init(&m->const_strings);
|
|
|
+ string16_map_init(&m->const_string16s);
|
|
|
map_init(&m->function_type_map);
|
|
|
string_map_init(&m->gen_procs);
|
|
|
if (USE_SEPARATE_MODULES) {
|
|
@@ -2716,7 +2717,18 @@ gb_internal LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String co
|
|
|
}
|
|
|
|
|
|
gb_internal LLVMValueRef lb_find_or_add_entity_string16_ptr(lbModule *m, String16 const &str, bool custom_link_section) {
|
|
|
- // TODO(bill): caching for UTF-16 strings
|
|
|
+ String16HashKey key = {};
|
|
|
+ LLVMValueRef *found = nullptr;
|
|
|
+
|
|
|
+ if (!custom_link_section) {
|
|
|
+ key = string_hash_string(str);
|
|
|
+ found = string16_map_get(&m->const_string16s, key);
|
|
|
+ }
|
|
|
+ if (found != nullptr) {
|
|
|
+ return *found;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
|
|
|
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
|
|
|
|
@@ -2749,6 +2761,9 @@ gb_internal LLVMValueRef lb_find_or_add_entity_string16_ptr(lbModule *m, String1
|
|
|
LLVMSetAlignment(global_data, 1);
|
|
|
|
|
|
LLVMValueRef ptr = LLVMConstInBoundsGEP2(type, global_data, indices, 2);
|
|
|
+ if (!custom_link_section) {
|
|
|
+ string16_map_set(&m->const_string16s, key, ptr);
|
|
|
+ }
|
|
|
return ptr;
|
|
|
}
|
|
|
|
|
@@ -2812,6 +2827,60 @@ gb_internal lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule *
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
+gb_internal lbValue lb_find_or_add_entity_string16_slice_with_type(lbModule *m, String16 const &str, Type *slice_type) {
|
|
|
+ GB_ASSERT(is_type_slice(slice_type));
|
|
|
+ LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
|
|
+ LLVMValueRef data = nullptr;
|
|
|
+ {
|
|
|
+ LLVMTypeRef llvm_u16 = LLVMInt16TypeInContext(m->ctx);
|
|
|
+
|
|
|
+ TEMPORARY_ALLOCATOR_GUARD();
|
|
|
+
|
|
|
+ LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, str.len+1);
|
|
|
+
|
|
|
+ for (isize i = 0; i < str.len; i++) {
|
|
|
+ values[i] = LLVMConstInt(llvm_u16, str.text[i], false);
|
|
|
+ }
|
|
|
+ values[str.len] = LLVMConstInt(llvm_u16, 0, false);
|
|
|
+
|
|
|
+ data = LLVMConstArray(llvm_u16, values, cast(unsigned)(str.len+1));
|
|
|
+ }
|
|
|
+
|
|
|
+ u32 id = m->global_array_index.fetch_add(1);
|
|
|
+ gbString name = gb_string_make(temporary_allocator(), "csba$");
|
|
|
+ name = gb_string_appendc(name, m->module_name);
|
|
|
+ name = gb_string_append_fmt(name, "$%x", id);
|
|
|
+
|
|
|
+ LLVMTypeRef type = LLVMTypeOf(data);
|
|
|
+ LLVMValueRef global_data = LLVMAddGlobal(m->mod, type, name);
|
|
|
+ LLVMSetInitializer(global_data, data);
|
|
|
+ lb_make_global_private_const(global_data);
|
|
|
+ LLVMSetAlignment(global_data, 1);
|
|
|
+
|
|
|
+ i64 data_len = str.len;
|
|
|
+ LLVMValueRef ptr = nullptr;
|
|
|
+ if (data_len != 0) {
|
|
|
+ ptr = LLVMConstInBoundsGEP2(type, global_data, indices, 2);
|
|
|
+ } else {
|
|
|
+ ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
|
|
|
+ }
|
|
|
+ if (!is_type_u16_slice(slice_type)) {
|
|
|
+ Type *bt = base_type(slice_type);
|
|
|
+ Type *elem = bt->Slice.elem;
|
|
|
+ i64 sz = type_size_of(elem);
|
|
|
+ GB_ASSERT(sz > 0);
|
|
|
+ ptr = LLVMConstPointerCast(ptr, lb_type(m, alloc_type_pointer(elem)));
|
|
|
+ data_len /= sz;
|
|
|
+ }
|
|
|
+
|
|
|
+ LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), data_len, true);
|
|
|
+ LLVMValueRef values[2] = {ptr, len};
|
|
|
+
|
|
|
+ lbValue res = {};
|
|
|
+ res.value = llvm_const_named_struct(m, slice_type, values, 2);
|
|
|
+ res.type = slice_type;
|
|
|
+ return res;
|
|
|
+}
|
|
|
|
|
|
|
|
|
gb_internal lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
|