mirror of
https://github.com/ziglang/zig.git
synced 2026-01-11 01:45:12 +00:00
better string literal caching implementation
We were caching the ConstExprValue of string literals, which works if you can never modify ConstExprValues. This premise is broken with `comptime var ...`. So I implemented an optimization in ConstExprValue arrays, where it stores a `Buf *` directly rather than an array of ConstExprValues for the elements, and then similar to array of undefined, it is expanded into the canonical form when necessary. However many operations can happen directly on the `Buf *`, which is faster. Furthermore, before a ConstExprValue array is expanded into canonical form, it removes itself from the string literal cache. This fixes the issue, because before an array element is modified it would have to be expanded. closes #1076
This commit is contained in:
parent
492821781d
commit
f8fe517d12
@ -130,14 +130,18 @@ struct ConstUnionValue {
|
||||
enum ConstArraySpecial {
|
||||
ConstArraySpecialNone,
|
||||
ConstArraySpecialUndef,
|
||||
ConstArraySpecialBuf,
|
||||
};
|
||||
|
||||
struct ConstArrayValue {
|
||||
ConstArraySpecial special;
|
||||
struct {
|
||||
ConstExprValue *elements;
|
||||
ConstParent parent;
|
||||
} s_none;
|
||||
union {
|
||||
struct {
|
||||
ConstExprValue *elements;
|
||||
ConstParent parent;
|
||||
} s_none;
|
||||
Buf *s_buf;
|
||||
} data;
|
||||
};
|
||||
|
||||
enum ConstPtrSpecial {
|
||||
@ -983,6 +987,7 @@ struct FnTypeParamInfo {
|
||||
};
|
||||
|
||||
struct GenericFnTypeId {
|
||||
CodeGen *codegen;
|
||||
ZigFn *fn_entry;
|
||||
ConstExprValue *params;
|
||||
size_t param_count;
|
||||
@ -1291,6 +1296,7 @@ struct FnExport {
|
||||
};
|
||||
|
||||
struct ZigFn {
|
||||
CodeGen *codegen;
|
||||
LLVMValueRef llvm_value;
|
||||
const char *llvm_name;
|
||||
AstNode *proto_node;
|
||||
@ -1848,13 +1854,14 @@ enum ScopeId {
|
||||
};
|
||||
|
||||
struct Scope {
|
||||
ScopeId id;
|
||||
CodeGen *codegen;
|
||||
AstNode *source_node;
|
||||
|
||||
// if the scope has a parent, this is it
|
||||
Scope *parent;
|
||||
|
||||
ZigLLVMDIScope *di_scope;
|
||||
ScopeId id;
|
||||
};
|
||||
|
||||
// This scope comes from global declarations or from
|
||||
|
||||
239
src/analyze.cpp
239
src/analyze.cpp
@ -92,62 +92,63 @@ ScopeDecls *get_container_scope(ZigType *type_entry) {
|
||||
return *get_container_scope_ptr(type_entry);
|
||||
}
|
||||
|
||||
void init_scope(Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) {
|
||||
void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) {
|
||||
dest->codegen = g;
|
||||
dest->id = id;
|
||||
dest->source_node = source_node;
|
||||
dest->parent = parent;
|
||||
}
|
||||
|
||||
ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) {
|
||||
ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) {
|
||||
assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr);
|
||||
ScopeDecls *scope = allocate<ScopeDecls>(1);
|
||||
init_scope(&scope->base, ScopeIdDecls, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdDecls, node, parent);
|
||||
scope->decl_table.init(4);
|
||||
scope->container_type = container_type;
|
||||
scope->import = import;
|
||||
return scope;
|
||||
}
|
||||
|
||||
ScopeBlock *create_block_scope(AstNode *node, Scope *parent) {
|
||||
ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeBlock);
|
||||
ScopeBlock *scope = allocate<ScopeBlock>(1);
|
||||
init_scope(&scope->base, ScopeIdBlock, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdBlock, node, parent);
|
||||
scope->name = node->data.block.name;
|
||||
return scope;
|
||||
}
|
||||
|
||||
ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) {
|
||||
ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeDefer);
|
||||
ScopeDefer *scope = allocate<ScopeDefer>(1);
|
||||
init_scope(&scope->base, ScopeIdDefer, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdDefer, node, parent);
|
||||
return scope;
|
||||
}
|
||||
|
||||
ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent) {
|
||||
ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeDefer);
|
||||
ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1);
|
||||
init_scope(&scope->base, ScopeIdDeferExpr, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdDeferExpr, node, parent);
|
||||
return scope;
|
||||
}
|
||||
|
||||
Scope *create_var_scope(AstNode *node, Scope *parent, ZigVar *var) {
|
||||
Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var) {
|
||||
ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);
|
||||
init_scope(&scope->base, ScopeIdVarDecl, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdVarDecl, node, parent);
|
||||
scope->var = var;
|
||||
return &scope->base;
|
||||
}
|
||||
|
||||
ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent) {
|
||||
ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeFnCallExpr);
|
||||
ScopeCImport *scope = allocate<ScopeCImport>(1);
|
||||
init_scope(&scope->base, ScopeIdCImport, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdCImport, node, parent);
|
||||
buf_resize(&scope->buf, 0);
|
||||
return scope;
|
||||
}
|
||||
|
||||
ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) {
|
||||
ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
ScopeLoop *scope = allocate<ScopeLoop>(1);
|
||||
init_scope(&scope->base, ScopeIdLoop, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdLoop, node, parent);
|
||||
if (node->type == NodeTypeWhileExpr) {
|
||||
scope->name = node->data.while_expr.name;
|
||||
} else if (node->type == NodeTypeForExpr) {
|
||||
@ -158,37 +159,37 @@ ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
Scope *create_runtime_scope(AstNode *node, Scope *parent, IrInstruction *is_comptime) {
|
||||
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime) {
|
||||
ScopeRuntime *scope = allocate<ScopeRuntime>(1);
|
||||
scope->is_comptime = is_comptime;
|
||||
init_scope(&scope->base, ScopeIdRuntime, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdRuntime, node, parent);
|
||||
return &scope->base;
|
||||
}
|
||||
|
||||
ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent) {
|
||||
ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeSuspend);
|
||||
ScopeSuspend *scope = allocate<ScopeSuspend>(1);
|
||||
init_scope(&scope->base, ScopeIdSuspend, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdSuspend, node, parent);
|
||||
return scope;
|
||||
}
|
||||
|
||||
ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, ZigFn *fn_entry) {
|
||||
ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry) {
|
||||
ScopeFnDef *scope = allocate<ScopeFnDef>(1);
|
||||
init_scope(&scope->base, ScopeIdFnDef, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdFnDef, node, parent);
|
||||
scope->fn_entry = fn_entry;
|
||||
return scope;
|
||||
}
|
||||
|
||||
Scope *create_comptime_scope(AstNode *node, Scope *parent) {
|
||||
Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
assert(node->type == NodeTypeCompTime || node->type == NodeTypeSwitchExpr);
|
||||
ScopeCompTime *scope = allocate<ScopeCompTime>(1);
|
||||
init_scope(&scope->base, ScopeIdCompTime, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdCompTime, node, parent);
|
||||
return &scope->base;
|
||||
}
|
||||
|
||||
Scope *create_coro_prelude_scope(AstNode *node, Scope *parent) {
|
||||
Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
ScopeCoroPrelude *scope = allocate<ScopeCoroPrelude>(1);
|
||||
init_scope(&scope->base, ScopeIdCoroPrelude, node, parent);
|
||||
init_scope(g, &scope->base, ScopeIdCoroPrelude, node, parent);
|
||||
return &scope->base;
|
||||
}
|
||||
|
||||
@ -204,9 +205,9 @@ ImportTableEntry *get_scope_import(Scope *scope) {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static ZigType *new_container_type_entry(ZigTypeId id, AstNode *source_node, Scope *parent_scope) {
|
||||
static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *source_node, Scope *parent_scope) {
|
||||
ZigType *entry = new_type_table_entry(id);
|
||||
*get_container_scope_ptr(entry) = create_decls_scope(source_node, parent_scope, entry, get_scope_import(parent_scope));
|
||||
*get_container_scope_ptr(entry) = create_decls_scope(g, source_node, parent_scope, entry, get_scope_import(parent_scope));
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -1245,7 +1246,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
|
||||
AstNode *decl_node, const char *name, ContainerLayout layout)
|
||||
{
|
||||
ZigTypeId type_id = container_to_type(kind);
|
||||
ZigType *entry = new_container_type_entry(type_id, decl_node, scope);
|
||||
ZigType *entry = new_container_type_entry(g, type_id, decl_node, scope);
|
||||
|
||||
switch (kind) {
|
||||
case ContainerKindStruct:
|
||||
@ -1372,13 +1373,17 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
|
||||
|
||||
assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
|
||||
ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
|
||||
if (array_val->data.x_array.special == ConstArraySpecialBuf) {
|
||||
*out_buffer = array_val->data.x_array.data.s_buf;
|
||||
return true;
|
||||
}
|
||||
expand_undef_array(g, array_val);
|
||||
size_t len = bigint_as_unsigned(&len_field->data.x_bigint);
|
||||
Buf *result = buf_alloc();
|
||||
buf_resize(result, len);
|
||||
for (size_t i = 0; i < len; i += 1) {
|
||||
size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;
|
||||
ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index];
|
||||
ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index];
|
||||
if (char_val->special == ConstValSpecialUndef) {
|
||||
add_node_error(g, node, buf_sprintf("use of undefined value"));
|
||||
return false;
|
||||
@ -3093,9 +3098,10 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) {
|
||||
buf_append_buf(buf, tld->name);
|
||||
}
|
||||
|
||||
ZigFn *create_fn_raw(FnInline inline_value) {
|
||||
ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) {
|
||||
ZigFn *fn_entry = allocate<ZigFn>(1);
|
||||
|
||||
fn_entry->codegen = g;
|
||||
fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
|
||||
fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota;
|
||||
fn_entry->analyzed_executable.fn_entry = fn_entry;
|
||||
@ -3105,12 +3111,12 @@ ZigFn *create_fn_raw(FnInline inline_value) {
|
||||
return fn_entry;
|
||||
}
|
||||
|
||||
ZigFn *create_fn(AstNode *proto_node) {
|
||||
ZigFn *create_fn(CodeGen *g, AstNode *proto_node) {
|
||||
assert(proto_node->type == NodeTypeFnProto);
|
||||
AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
|
||||
|
||||
FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;
|
||||
ZigFn *fn_entry = create_fn_raw(inline_value);
|
||||
ZigFn *fn_entry = create_fn_raw(g, inline_value);
|
||||
|
||||
fn_entry->proto_node = proto_node;
|
||||
fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr :
|
||||
@ -3209,7 +3215,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
|
||||
|
||||
AstNode *fn_def_node = fn_proto->fn_def_node;
|
||||
|
||||
ZigFn *fn_table_entry = create_fn(source_node);
|
||||
ZigFn *fn_table_entry = create_fn(g, source_node);
|
||||
get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
|
||||
|
||||
if (fn_proto->is_export) {
|
||||
@ -3220,7 +3226,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
|
||||
tld_fn->fn_entry = fn_table_entry;
|
||||
|
||||
if (fn_table_entry->body_node) {
|
||||
fn_table_entry->fndef_scope = create_fndef_scope(
|
||||
fn_table_entry->fndef_scope = create_fndef_scope(g,
|
||||
fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry);
|
||||
|
||||
for (size_t i = 0; i < fn_proto->params.length; i += 1) {
|
||||
@ -3270,14 +3276,14 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
|
||||
}
|
||||
}
|
||||
} else if (source_node->type == NodeTypeTestDecl) {
|
||||
ZigFn *fn_table_entry = create_fn_raw(FnInlineAuto);
|
||||
ZigFn *fn_table_entry = create_fn_raw(g, FnInlineAuto);
|
||||
|
||||
get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
|
||||
|
||||
tld_fn->fn_entry = fn_table_entry;
|
||||
|
||||
fn_table_entry->proto_node = source_node;
|
||||
fn_table_entry->fndef_scope = create_fndef_scope(source_node, tld_fn->base.parent_scope, fn_table_entry);
|
||||
fn_table_entry->fndef_scope = create_fndef_scope(g, source_node, tld_fn->base.parent_scope, fn_table_entry);
|
||||
fn_table_entry->type_entry = get_test_fn_type(g);
|
||||
fn_table_entry->body_node = source_node->data.test_decl.body;
|
||||
fn_table_entry->is_test = true;
|
||||
@ -3606,7 +3612,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
|
||||
|
||||
Scope *child_scope;
|
||||
if (source_node && source_node->type == NodeTypeParamDecl) {
|
||||
child_scope = create_var_scope(source_node, parent_scope, variable_entry);
|
||||
child_scope = create_var_scope(g, source_node, parent_scope, variable_entry);
|
||||
} else {
|
||||
// it's already in the decls table
|
||||
child_scope = parent_scope;
|
||||
@ -4329,7 +4335,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r
|
||||
g->import_table.put(resolved_path, import_entry);
|
||||
g->import_queue.append(import_entry);
|
||||
|
||||
import_entry->decls_scope = create_decls_scope(import_entry->root, nullptr, nullptr, import_entry);
|
||||
import_entry->decls_scope = create_decls_scope(g, import_entry->root, nullptr, nullptr, import_entry);
|
||||
|
||||
|
||||
assert(import_entry->root->type == NodeTypeRoot);
|
||||
@ -4880,7 +4886,7 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {
|
||||
if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) {
|
||||
assert(a_val->special == ConstValSpecialStatic);
|
||||
assert(b_val->special == ConstValSpecialStatic);
|
||||
if (!const_values_equal(a_val, b_val)) {
|
||||
if (!const_values_equal(a->fn_entry->codegen, a_val, b_val)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@ -4920,14 +4926,18 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
|
||||
case ZigTypeIdArray:
|
||||
if (value->type->data.array.len == 0)
|
||||
return false;
|
||||
if (value->data.x_array.special == ConstArraySpecialUndef)
|
||||
return false;
|
||||
for (uint32_t i = 0; i < value->type->data.array.len; i += 1) {
|
||||
if (can_mutate_comptime_var_state(&value->data.x_array.s_none.elements[i]))
|
||||
return true;
|
||||
switch (value->data.x_array.special) {
|
||||
case ConstArraySpecialUndef:
|
||||
case ConstArraySpecialBuf:
|
||||
return false;
|
||||
case ConstArraySpecialNone:
|
||||
for (uint32_t i = 0; i < value->type->data.array.len; i += 1) {
|
||||
if (can_mutate_comptime_var_state(&value->data.x_array.data.s_none.elements[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
zig_unreachable();
|
||||
case ZigTypeIdStruct:
|
||||
for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) {
|
||||
if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i]))
|
||||
@ -5039,6 +5049,8 @@ uint32_t fn_eval_hash(Scope* scope) {
|
||||
}
|
||||
|
||||
bool fn_eval_eql(Scope *a, Scope *b) {
|
||||
assert(a->codegen != nullptr);
|
||||
assert(b->codegen != nullptr);
|
||||
while (a && b) {
|
||||
if (a->id != b->id)
|
||||
return false;
|
||||
@ -5048,7 +5060,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {
|
||||
ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b;
|
||||
if (a_var_scope->var->value->type != b_var_scope->var->value->type)
|
||||
return false;
|
||||
if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value))
|
||||
if (!const_values_equal(a->codegen, a_var_scope->var->value, b_var_scope->var->value))
|
||||
return false;
|
||||
} else if (a->id == ScopeIdFnDef) {
|
||||
ScopeFnDef *a_fn_scope = (ScopeFnDef *)a;
|
||||
@ -5130,14 +5142,8 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
|
||||
|
||||
const_val->special = ConstValSpecialStatic;
|
||||
const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));
|
||||
const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str));
|
||||
|
||||
for (size_t i = 0; i < buf_len(str); i += 1) {
|
||||
ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i];
|
||||
this_char->special = ConstValSpecialStatic;
|
||||
this_char->type = g->builtin_types.entry_u8;
|
||||
bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);
|
||||
}
|
||||
const_val->data.x_array.special = ConstArraySpecialBuf;
|
||||
const_val->data.x_array.data.s_buf = str;
|
||||
|
||||
g->string_literals_table.put(str, const_val);
|
||||
}
|
||||
@ -5154,14 +5160,15 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
|
||||
ConstExprValue *array_val = create_const_vals(1);
|
||||
array_val->special = ConstValSpecialStatic;
|
||||
array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);
|
||||
array_val->data.x_array.s_none.elements = create_const_vals(len_with_null);
|
||||
// TODO buf optimization
|
||||
array_val->data.x_array.data.s_none.elements = create_const_vals(len_with_null);
|
||||
for (size_t i = 0; i < buf_len(str); i += 1) {
|
||||
ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i];
|
||||
ConstExprValue *this_char = &array_val->data.x_array.data.s_none.elements[i];
|
||||
this_char->special = ConstValSpecialStatic;
|
||||
this_char->type = g->builtin_types.entry_u8;
|
||||
bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);
|
||||
}
|
||||
ConstExprValue *null_char = &array_val->data.x_array.s_none.elements[len_with_null - 1];
|
||||
ConstExprValue *null_char = &array_val->data.x_array.data.s_none.elements[len_with_null - 1];
|
||||
null_char->special = ConstValSpecialStatic;
|
||||
null_char->type = g->builtin_types.entry_u8;
|
||||
bigint_init_unsigned(&null_char->data.x_bigint, 0);
|
||||
@ -5535,7 +5542,7 @@ bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
|
||||
bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
|
||||
assert(a->type->id == b->type->id);
|
||||
assert(a->special == ConstValSpecialStatic);
|
||||
assert(b->special == ConstValSpecialStatic);
|
||||
@ -5593,13 +5600,20 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
|
||||
assert(a->type->data.array.len == b->type->data.array.len);
|
||||
assert(a->data.x_array.special != ConstArraySpecialUndef);
|
||||
assert(b->data.x_array.special != ConstArraySpecialUndef);
|
||||
if (a->data.x_array.special == ConstArraySpecialBuf &&
|
||||
b->data.x_array.special == ConstArraySpecialBuf)
|
||||
{
|
||||
return buf_eql_buf(a->data.x_array.data.s_buf, b->data.x_array.data.s_buf);
|
||||
}
|
||||
expand_undef_array(g, a);
|
||||
expand_undef_array(g, b);
|
||||
|
||||
size_t len = a->type->data.array.len;
|
||||
ConstExprValue *a_elems = a->data.x_array.s_none.elements;
|
||||
ConstExprValue *b_elems = b->data.x_array.s_none.elements;
|
||||
ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;
|
||||
ConstExprValue *b_elems = b->data.x_array.data.s_none.elements;
|
||||
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
if (!const_values_equal(&a_elems[i], &b_elems[i]))
|
||||
if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5609,7 +5623,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
|
||||
for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {
|
||||
ConstExprValue *field_a = &a->data.x_struct.fields[i];
|
||||
ConstExprValue *field_b = &b->data.x_struct.fields[i];
|
||||
if (!const_values_equal(field_a, field_b))
|
||||
if (!const_values_equal(g, field_a, field_b))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -5623,7 +5637,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
|
||||
if (a->data.x_optional == nullptr || b->data.x_optional == nullptr) {
|
||||
return (a->data.x_optional == nullptr && b->data.x_optional == nullptr);
|
||||
} else {
|
||||
return const_values_equal(a->data.x_optional, b->data.x_optional);
|
||||
return const_values_equal(g, a->data.x_optional, b->data.x_optional);
|
||||
}
|
||||
case ZigTypeIdErrorUnion:
|
||||
zig_panic("TODO");
|
||||
@ -5808,26 +5822,15 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
|
||||
case ZigTypeIdPointer:
|
||||
return render_const_val_ptr(g, buf, const_val, type_entry);
|
||||
case ZigTypeIdArray:
|
||||
{
|
||||
ZigType *child_type = type_entry->data.array.child_type;
|
||||
uint64_t len = type_entry->data.array.len;
|
||||
|
||||
if (const_val->data.x_array.special == ConstArraySpecialUndef) {
|
||||
switch (const_val->data.x_array.special) {
|
||||
case ConstArraySpecialUndef:
|
||||
buf_append_str(buf, "undefined");
|
||||
return;
|
||||
}
|
||||
|
||||
// if it's []u8, assume UTF-8 and output a string
|
||||
if (child_type->id == ZigTypeIdInt &&
|
||||
child_type->data.integral.bit_count == 8 &&
|
||||
!child_type->data.integral.is_signed)
|
||||
{
|
||||
case ConstArraySpecialBuf: {
|
||||
Buf *array_buf = const_val->data.x_array.data.s_buf;
|
||||
buf_append_char(buf, '"');
|
||||
for (uint64_t i = 0; i < len; i += 1) {
|
||||
ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i];
|
||||
uint64_t big_c = bigint_as_unsigned(&child_value->data.x_bigint);
|
||||
assert(big_c <= UINT8_MAX);
|
||||
uint8_t c = (uint8_t)big_c;
|
||||
for (size_t i = 0; i < buf_len(array_buf); i += 1) {
|
||||
uint8_t c = buf_ptr(array_buf)[i];
|
||||
if (c == '"') {
|
||||
buf_append_str(buf, "\\\"");
|
||||
} else {
|
||||
@ -5837,17 +5840,20 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
|
||||
buf_append_char(buf, '"');
|
||||
return;
|
||||
}
|
||||
|
||||
buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));
|
||||
for (uint64_t i = 0; i < len; i += 1) {
|
||||
if (i != 0)
|
||||
buf_appendf(buf, ",");
|
||||
ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i];
|
||||
render_const_value(g, buf, child_value);
|
||||
case ConstArraySpecialNone: {
|
||||
buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));
|
||||
uint64_t len = type_entry->data.array.len;
|
||||
for (uint64_t i = 0; i < len; i += 1) {
|
||||
if (i != 0)
|
||||
buf_appendf(buf, ",");
|
||||
ConstExprValue *child_value = &const_val->data.x_array.data.s_none.elements[i];
|
||||
render_const_value(g, buf, child_value);
|
||||
}
|
||||
buf_appendf(buf, "}");
|
||||
return;
|
||||
}
|
||||
buf_appendf(buf, "}");
|
||||
return;
|
||||
}
|
||||
zig_unreachable();
|
||||
case ZigTypeIdNull:
|
||||
{
|
||||
buf_appendf(buf, "null");
|
||||
@ -6102,24 +6108,49 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
// Canonicalize the array value as ConstArraySpecialNone
|
||||
void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
|
||||
assert(const_val->type->id == ZigTypeIdArray);
|
||||
if (const_val->data.x_array.special == ConstArraySpecialUndef) {
|
||||
const_val->data.x_array.special = ConstArraySpecialNone;
|
||||
size_t elem_count = const_val->type->data.array.len;
|
||||
const_val->data.x_array.s_none.elements = create_const_vals(elem_count);
|
||||
for (size_t i = 0; i < elem_count; i += 1) {
|
||||
ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i];
|
||||
element_val->type = const_val->type->data.array.child_type;
|
||||
init_const_undefined(g, element_val);
|
||||
ConstParent *parent = get_const_val_parent(g, element_val);
|
||||
if (parent != nullptr) {
|
||||
parent->id = ConstParentIdArray;
|
||||
parent->data.p_array.array_val = const_val;
|
||||
parent->data.p_array.elem_index = i;
|
||||
switch (const_val->data.x_array.special) {
|
||||
case ConstArraySpecialNone:
|
||||
return;
|
||||
case ConstArraySpecialUndef: {
|
||||
const_val->data.x_array.special = ConstArraySpecialNone;
|
||||
size_t elem_count = const_val->type->data.array.len;
|
||||
const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
|
||||
for (size_t i = 0; i < elem_count; i += 1) {
|
||||
ConstExprValue *element_val = &const_val->data.x_array.data.s_none.elements[i];
|
||||
element_val->type = const_val->type->data.array.child_type;
|
||||
init_const_undefined(g, element_val);
|
||||
ConstParent *parent = get_const_val_parent(g, element_val);
|
||||
if (parent != nullptr) {
|
||||
parent->id = ConstParentIdArray;
|
||||
parent->data.p_array.array_val = const_val;
|
||||
parent->data.p_array.elem_index = i;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
case ConstArraySpecialBuf: {
|
||||
Buf *buf = const_val->data.x_array.data.s_buf;
|
||||
// If we're doing this it means that we are potentially modifying the data,
|
||||
// so we can't have it be in the string literals table
|
||||
g->string_literals_table.maybe_remove(buf);
|
||||
|
||||
const_val->data.x_array.special = ConstArraySpecialNone;
|
||||
size_t elem_count = const_val->type->data.array.len;
|
||||
assert(elem_count == buf_len(buf));
|
||||
const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
|
||||
for (size_t i = 0; i < elem_count; i += 1) {
|
||||
ConstExprValue *this_char = &const_val->data.x_array.data.s_none.elements[i];
|
||||
this_char->special = ConstValSpecialStatic;
|
||||
this_char->type = g->builtin_types.entry_u8;
|
||||
bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(buf)[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
|
||||
@ -6127,7 +6158,7 @@ ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
|
||||
ZigType *type_entry = value->type;
|
||||
if (type_entry->id == ZigTypeIdArray) {
|
||||
expand_undef_array(g, value);
|
||||
return &value->data.x_array.s_none.parent;
|
||||
return &value->data.x_array.data.s_none.parent;
|
||||
} else if (type_entry->id == ZigTypeIdStruct) {
|
||||
return &value->data.x_struct.parent;
|
||||
} else if (type_entry->id == ZigTypeIdUnion) {
|
||||
|
||||
@ -84,8 +84,8 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source
|
||||
ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name,
|
||||
bool is_const, ConstExprValue *init_value, Tld *src_tld);
|
||||
ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node);
|
||||
ZigFn *create_fn(AstNode *proto_node);
|
||||
ZigFn *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage);
|
||||
ZigFn *create_fn(CodeGen *g, AstNode *proto_node);
|
||||
ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value);
|
||||
void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc);
|
||||
AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index);
|
||||
bool type_requires_comptime(ZigType *type_entry);
|
||||
@ -93,25 +93,25 @@ Error ATTRIBUTE_MUST_USE ensure_complete_type(CodeGen *g, ZigType *type_entry);
|
||||
Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status);
|
||||
void complete_enum(CodeGen *g, ZigType *enum_type);
|
||||
bool ir_get_var_is_comptime(ZigVar *var);
|
||||
bool const_values_equal(ConstExprValue *a, ConstExprValue *b);
|
||||
bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b);
|
||||
void eval_min_max_value(CodeGen *g, ZigType *type_entry, ConstExprValue *const_val, bool is_max);
|
||||
void eval_min_max_value_int(CodeGen *g, ZigType *int_type, BigInt *bigint, bool is_max);
|
||||
|
||||
void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val);
|
||||
void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_type_node);
|
||||
|
||||
ScopeBlock *create_block_scope(AstNode *node, Scope *parent);
|
||||
ScopeDefer *create_defer_scope(AstNode *node, Scope *parent);
|
||||
ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent);
|
||||
Scope *create_var_scope(AstNode *node, Scope *parent, ZigVar *var);
|
||||
ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent);
|
||||
ScopeLoop *create_loop_scope(AstNode *node, Scope *parent);
|
||||
ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent);
|
||||
ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, ZigFn *fn_entry);
|
||||
ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import);
|
||||
Scope *create_comptime_scope(AstNode *node, Scope *parent);
|
||||
Scope *create_coro_prelude_scope(AstNode *node, Scope *parent);
|
||||
Scope *create_runtime_scope(AstNode *node, Scope *parent, IrInstruction *is_comptime);
|
||||
ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var);
|
||||
ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
|
||||
ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import);
|
||||
Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime);
|
||||
|
||||
void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str);
|
||||
ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str);
|
||||
|
||||
@ -5336,7 +5336,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent
|
||||
|
||||
static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) {
|
||||
expand_undef_array(g, array_const_val);
|
||||
ConstParent *parent = &array_const_val->data.x_array.s_none.parent;
|
||||
ConstParent *parent = &array_const_val->data.x_array.data.s_none.parent;
|
||||
LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);
|
||||
|
||||
LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr)));
|
||||
@ -5716,23 +5716,29 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
|
||||
case ZigTypeIdArray:
|
||||
{
|
||||
uint64_t len = type_entry->data.array.len;
|
||||
if (const_val->data.x_array.special == ConstArraySpecialUndef) {
|
||||
return LLVMGetUndef(type_entry->type_ref);
|
||||
}
|
||||
|
||||
LLVMValueRef *values = allocate<LLVMValueRef>(len);
|
||||
LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref;
|
||||
bool make_unnamed_struct = false;
|
||||
for (uint64_t i = 0; i < len; i += 1) {
|
||||
ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i];
|
||||
LLVMValueRef val = gen_const_val(g, elem_value, "");
|
||||
values[i] = val;
|
||||
make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val);
|
||||
}
|
||||
if (make_unnamed_struct) {
|
||||
return LLVMConstStruct(values, len, true);
|
||||
} else {
|
||||
return LLVMConstArray(element_type_ref, values, (unsigned)len);
|
||||
switch (const_val->data.x_array.special) {
|
||||
case ConstArraySpecialUndef:
|
||||
return LLVMGetUndef(type_entry->type_ref);
|
||||
case ConstArraySpecialNone: {
|
||||
LLVMValueRef *values = allocate<LLVMValueRef>(len);
|
||||
LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref;
|
||||
bool make_unnamed_struct = false;
|
||||
for (uint64_t i = 0; i < len; i += 1) {
|
||||
ConstExprValue *elem_value = &const_val->data.x_array.data.s_none.elements[i];
|
||||
LLVMValueRef val = gen_const_val(g, elem_value, "");
|
||||
values[i] = val;
|
||||
make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val);
|
||||
}
|
||||
if (make_unnamed_struct) {
|
||||
return LLVMConstStruct(values, len, true);
|
||||
} else {
|
||||
return LLVMConstArray(element_type_ref, values, (unsigned)len);
|
||||
}
|
||||
}
|
||||
case ConstArraySpecialBuf: {
|
||||
Buf *buf = const_val->data.x_array.data.s_buf;
|
||||
return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
case ZigTypeIdUnion:
|
||||
@ -7278,7 +7284,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) {
|
||||
import->source_code = nullptr;
|
||||
import->path = full_path;
|
||||
g->root_import = import;
|
||||
import->decls_scope = create_decls_scope(nullptr, nullptr, nullptr, import);
|
||||
import->decls_scope = create_decls_scope(g, nullptr, nullptr, nullptr, import);
|
||||
|
||||
init(g);
|
||||
|
||||
@ -7352,12 +7358,12 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
|
||||
ConstExprValue *test_fn_array = create_const_vals(1);
|
||||
test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length);
|
||||
test_fn_array->special = ConstValSpecialStatic;
|
||||
test_fn_array->data.x_array.s_none.elements = create_const_vals(g->test_fns.length);
|
||||
test_fn_array->data.x_array.data.s_none.elements = create_const_vals(g->test_fns.length);
|
||||
|
||||
for (size_t i = 0; i < g->test_fns.length; i += 1) {
|
||||
ZigFn *test_fn_entry = g->test_fns.at(i);
|
||||
|
||||
ConstExprValue *this_val = &test_fn_array->data.x_array.s_none.elements[i];
|
||||
ConstExprValue *this_val = &test_fn_array->data.x_array.data.s_none.elements[i];
|
||||
this_val->special = ConstValSpecialStatic;
|
||||
this_val->type = struct_type;
|
||||
this_val->data.x_struct.parent.id = ConstParentIdArray;
|
||||
|
||||
135
src/ir.cpp
135
src/ir.cpp
@ -166,7 +166,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
|
||||
break;
|
||||
case ConstPtrSpecialBaseArray:
|
||||
expand_undef_array(g, const_val->data.x_ptr.data.base_array.array_val);
|
||||
result = &const_val->data.x_ptr.data.base_array.array_val->data.x_array.s_none.elements[
|
||||
result = &const_val->data.x_ptr.data.base_array.array_val->data.x_array.data.s_none.elements[
|
||||
const_val->data.x_ptr.data.base_array.elem_index];
|
||||
break;
|
||||
case ConstPtrSpecialBaseStruct:
|
||||
@ -3360,7 +3360,7 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s
|
||||
variable_entry->src_is_const = src_is_const;
|
||||
variable_entry->gen_is_const = gen_is_const;
|
||||
variable_entry->decl_node = node;
|
||||
variable_entry->child_scope = create_var_scope(node, parent_scope, variable_entry);
|
||||
variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry);
|
||||
|
||||
return variable_entry;
|
||||
}
|
||||
@ -3388,7 +3388,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
|
||||
ZigList<IrInstruction *> incoming_values = {0};
|
||||
ZigList<IrBasicBlock *> incoming_blocks = {0};
|
||||
|
||||
ScopeBlock *scope_block = create_block_scope(block_node, parent_scope);
|
||||
ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope);
|
||||
|
||||
Scope *outer_block_scope = &scope_block->base;
|
||||
Scope *child_scope = outer_block_scope;
|
||||
@ -5026,7 +5026,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, then_block);
|
||||
|
||||
Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
|
||||
Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
|
||||
IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope);
|
||||
if (then_expr_result == irb->codegen->invalid_instruction)
|
||||
return then_expr_result;
|
||||
@ -5318,7 +5318,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
|
||||
ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline);
|
||||
ir_build_br(irb, scope, node, cond_block, is_comptime);
|
||||
|
||||
Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
|
||||
Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
|
||||
Buf *var_symbol = node->data.while_expr.var_symbol;
|
||||
Buf *err_symbol = node->data.while_expr.err_symbol;
|
||||
if (err_symbol != nullptr) {
|
||||
@ -5359,7 +5359,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
|
||||
ZigList<IrInstruction *> incoming_values = {0};
|
||||
ZigList<IrBasicBlock *> incoming_blocks = {0};
|
||||
|
||||
ScopeLoop *loop_scope = create_loop_scope(node, payload_scope);
|
||||
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope);
|
||||
loop_scope->break_block = end_block;
|
||||
loop_scope->continue_block = continue_block;
|
||||
loop_scope->is_comptime = is_comptime;
|
||||
@ -5415,7 +5415,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
|
||||
return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
|
||||
} else if (var_symbol != nullptr) {
|
||||
ir_set_cursor_at_end_and_append_block(irb, cond_block);
|
||||
Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
|
||||
Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
|
||||
// TODO make it an error to write to payload variable
|
||||
AstNode *symbol_node = node; // TODO make more accurate
|
||||
|
||||
@ -5443,7 +5443,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
|
||||
ZigList<IrInstruction *> incoming_values = {0};
|
||||
ZigList<IrBasicBlock *> incoming_blocks = {0};
|
||||
|
||||
ScopeLoop *loop_scope = create_loop_scope(node, child_scope);
|
||||
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
|
||||
loop_scope->break_block = end_block;
|
||||
loop_scope->continue_block = continue_block;
|
||||
loop_scope->is_comptime = is_comptime;
|
||||
@ -5506,9 +5506,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
|
||||
ZigList<IrInstruction *> incoming_values = {0};
|
||||
ZigList<IrBasicBlock *> incoming_blocks = {0};
|
||||
|
||||
Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
|
||||
Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
|
||||
|
||||
ScopeLoop *loop_scope = create_loop_scope(node, subexpr_scope);
|
||||
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope);
|
||||
loop_scope->break_block = end_block;
|
||||
loop_scope->continue_block = continue_block;
|
||||
loop_scope->is_comptime = is_comptime;
|
||||
@ -5645,7 +5645,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
|
||||
|
||||
ZigList<IrInstruction *> incoming_values = {0};
|
||||
ZigList<IrBasicBlock *> incoming_blocks = {0};
|
||||
ScopeLoop *loop_scope = create_loop_scope(node, child_scope);
|
||||
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
|
||||
loop_scope->break_block = end_block;
|
||||
loop_scope->continue_block = continue_block;
|
||||
loop_scope->is_comptime = is_comptime;
|
||||
@ -5855,7 +5855,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, then_block);
|
||||
|
||||
Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
|
||||
Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
|
||||
Scope *var_scope;
|
||||
if (var_symbol) {
|
||||
IrInstruction *var_type = nullptr;
|
||||
@ -5930,7 +5930,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
|
||||
|
||||
ir_set_cursor_at_end_and_append_block(irb, ok_block);
|
||||
|
||||
Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
|
||||
Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
|
||||
Scope *var_scope;
|
||||
if (var_symbol) {
|
||||
IrInstruction *var_type = nullptr;
|
||||
@ -6066,8 +6066,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
|
||||
ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0};
|
||||
|
||||
// First do the else and the ranges
|
||||
Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);
|
||||
Scope *comptime_scope = create_comptime_scope(node, scope);
|
||||
Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
|
||||
Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
|
||||
AstNode *else_prong = nullptr;
|
||||
for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
|
||||
AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
|
||||
@ -6231,7 +6231,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
|
||||
static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) {
|
||||
assert(node->type == NodeTypeCompTime);
|
||||
|
||||
Scope *child_scope = create_comptime_scope(node, parent_scope);
|
||||
Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope);
|
||||
return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval);
|
||||
}
|
||||
|
||||
@ -6394,10 +6394,10 @@ static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *n
|
||||
static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
|
||||
assert(node->type == NodeTypeDefer);
|
||||
|
||||
ScopeDefer *defer_child_scope = create_defer_scope(node, parent_scope);
|
||||
ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope);
|
||||
node->data.defer.child_scope = &defer_child_scope->base;
|
||||
|
||||
ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(node, parent_scope);
|
||||
ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope);
|
||||
node->data.defer.expr_scope = &defer_expr_scope->base;
|
||||
|
||||
return ir_build_const_void(irb, parent_scope, node);
|
||||
@ -7154,7 +7154,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
|
||||
suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false);
|
||||
} else {
|
||||
Scope *child_scope;
|
||||
ScopeSuspend *suspend_scope = create_suspend_scope(node, parent_scope);
|
||||
ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope);
|
||||
suspend_scope->resume_block = resume_block;
|
||||
child_scope = &suspend_scope->base;
|
||||
IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle);
|
||||
@ -7370,7 +7370,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
|
||||
ZigVar *coro_size_var;
|
||||
if (is_async) {
|
||||
// create the coro promise
|
||||
Scope *coro_scope = create_coro_prelude_scope(node, scope);
|
||||
Scope *coro_scope = create_coro_prelude_scope(irb->codegen, node, scope);
|
||||
const_bool_false = ir_build_const_bool(irb, coro_scope, node, false);
|
||||
ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
|
||||
|
||||
@ -10569,9 +10569,9 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou
|
||||
array_val->special = ConstValSpecialStatic;
|
||||
array_val->type = array_type;
|
||||
array_val->data.x_array.special = ConstArraySpecialNone;
|
||||
array_val->data.x_array.s_none.elements = pointee;
|
||||
array_val->data.x_array.s_none.parent.id = ConstParentIdScalar;
|
||||
array_val->data.x_array.s_none.parent.data.p_scalar.scalar_val = pointee;
|
||||
array_val->data.x_array.data.s_none.elements = pointee;
|
||||
array_val->data.x_array.data.s_none.parent.id = ConstParentIdScalar;
|
||||
array_val->data.x_array.data.s_none.parent.data.p_scalar.scalar_val = pointee;
|
||||
|
||||
IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
|
||||
source_instr->scope, source_instr->source_node);
|
||||
@ -11391,13 +11391,16 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
|
||||
|
||||
assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
|
||||
ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
|
||||
if (array_val->data.x_array.special == ConstArraySpecialBuf) {
|
||||
return array_val->data.x_array.data.s_buf;
|
||||
}
|
||||
expand_undef_array(ira->codegen, array_val);
|
||||
size_t len = bigint_as_unsigned(&len_field->data.x_bigint);
|
||||
Buf *result = buf_alloc();
|
||||
buf_resize(result, len);
|
||||
for (size_t i = 0; i < len; i += 1) {
|
||||
size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;
|
||||
ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index];
|
||||
ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index];
|
||||
if (char_val->special == ConstValSpecialUndef) {
|
||||
ir_add_error(ira, casted_value, buf_sprintf("use of undefined value"));
|
||||
return nullptr;
|
||||
@ -11750,7 +11753,7 @@ static ZigType *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op
|
||||
Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);
|
||||
answer = resolve_cmp_op_id(op_id, cmp_result);
|
||||
} else {
|
||||
bool are_equal = one_possible_value || const_values_equal(op1_val, op2_val);
|
||||
bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val);
|
||||
if (op_id == IrBinOpCmpEq) {
|
||||
answer = are_equal;
|
||||
} else if (op_id == IrBinOpCmpNotEq) {
|
||||
@ -12463,19 +12466,20 @@ static ZigType *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruc
|
||||
return result_type;
|
||||
}
|
||||
|
||||
out_array_val->data.x_array.s_none.elements = create_const_vals(new_len);
|
||||
out_array_val->data.x_array.data.s_none.elements = create_const_vals(new_len);
|
||||
// TODO handle the buf case here for an optimization
|
||||
expand_undef_array(ira->codegen, op1_array_val);
|
||||
expand_undef_array(ira->codegen, op2_array_val);
|
||||
|
||||
size_t next_index = 0;
|
||||
for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) {
|
||||
out_array_val->data.x_array.s_none.elements[next_index] = op1_array_val->data.x_array.s_none.elements[i];
|
||||
out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i];
|
||||
}
|
||||
for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) {
|
||||
out_array_val->data.x_array.s_none.elements[next_index] = op2_array_val->data.x_array.s_none.elements[i];
|
||||
out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i];
|
||||
}
|
||||
if (next_index < new_len) {
|
||||
ConstExprValue *null_byte = &out_array_val->data.x_array.s_none.elements[next_index];
|
||||
ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index];
|
||||
init_const_unsigned_negative(null_byte, child_type, 0, false);
|
||||
next_index += 1;
|
||||
}
|
||||
@ -12524,12 +12528,14 @@ static ZigType *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instru
|
||||
return get_array_type(ira->codegen, child_type, new_array_len);
|
||||
}
|
||||
|
||||
out_val->data.x_array.s_none.elements = create_const_vals(new_array_len);
|
||||
// TODO optimize the buf case
|
||||
expand_undef_array(ira->codegen, array_val);
|
||||
out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len);
|
||||
|
||||
uint64_t i = 0;
|
||||
for (uint64_t x = 0; x < mult_amt; x += 1) {
|
||||
for (uint64_t y = 0; y < old_array_len; y += 1) {
|
||||
out_val->data.x_array.s_none.elements[i] = array_val->data.x_array.s_none.elements[y];
|
||||
out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y];
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
@ -13502,10 +13508,10 @@ static ZigType *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instr
|
||||
|
||||
// Fork a scope of the function with known values for the parameters.
|
||||
Scope *parent_scope = fn_entry->fndef_scope->base.parent;
|
||||
ZigFn *impl_fn = create_fn(fn_proto_node);
|
||||
ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node);
|
||||
impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count);
|
||||
buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
|
||||
impl_fn->fndef_scope = create_fndef_scope(impl_fn->body_node, parent_scope, impl_fn);
|
||||
impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn);
|
||||
impl_fn->child_scope = &impl_fn->fndef_scope->base;
|
||||
FnTypeId inst_fn_type_id = {0};
|
||||
init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count);
|
||||
@ -16073,7 +16079,7 @@ static ZigType *ir_analyze_instruction_switch_br(IrAnalyze *ira,
|
||||
if (!case_val)
|
||||
return ir_unreach_error(ira);
|
||||
|
||||
if (const_values_equal(target_val, case_val)) {
|
||||
if (const_values_equal(ira->codegen, target_val, case_val)) {
|
||||
old_dest_block = old_case->block;
|
||||
break;
|
||||
}
|
||||
@ -16652,7 +16658,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
|
||||
ConstExprValue const_val = {};
|
||||
const_val.special = ConstValSpecialStatic;
|
||||
const_val.type = fixed_size_array_type;
|
||||
const_val.data.x_array.s_none.elements = create_const_vals(elem_count);
|
||||
const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count);
|
||||
|
||||
bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
|
||||
|
||||
@ -16677,7 +16683,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
|
||||
if (!elem_val)
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
||||
copy_const_val(&const_val.data.x_array.s_none.elements[i], elem_val, true);
|
||||
copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true);
|
||||
} else {
|
||||
first_non_const_instruction = casted_arg;
|
||||
const_val.special = ConstValSpecialRuntime;
|
||||
@ -16689,7 +16695,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
|
||||
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
|
||||
*out_val = const_val;
|
||||
for (size_t i = 0; i < elem_count; i += 1) {
|
||||
ConstExprValue *elem_val = &out_val->data.x_array.s_none.elements[i];
|
||||
ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i];
|
||||
ConstParent *parent = get_const_val_parent(ira->codegen, elem_val);
|
||||
if (parent != nullptr) {
|
||||
parent->id = ConstParentIdArray;
|
||||
@ -17146,8 +17152,8 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
|
||||
definition_array->special = ConstValSpecialStatic;
|
||||
definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count);
|
||||
definition_array->data.x_array.special = ConstArraySpecialNone;
|
||||
definition_array->data.x_array.s_none.parent.id = ConstParentIdNone;
|
||||
definition_array->data.x_array.s_none.elements = create_const_vals(definition_count);
|
||||
definition_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
|
||||
definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count);
|
||||
init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false);
|
||||
|
||||
// Loop through the definitions and generate info.
|
||||
@ -17164,7 +17170,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
|
||||
continue;
|
||||
}
|
||||
|
||||
ConstExprValue *definition_val = &definition_array->data.x_array.s_none.elements[definition_index];
|
||||
ConstExprValue *definition_val = &definition_array->data.x_array.data.s_none.elements[definition_index];
|
||||
|
||||
definition_val->special = ConstValSpecialStatic;
|
||||
definition_val->type = type_info_definition_type;
|
||||
@ -17293,15 +17299,15 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
|
||||
fn_arg_name_array->type = get_array_type(ira->codegen,
|
||||
get_slice_type(ira->codegen, u8_ptr), fn_arg_count);
|
||||
fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;
|
||||
fn_arg_name_array->data.x_array.s_none.parent.id = ConstParentIdNone;
|
||||
fn_arg_name_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count);
|
||||
fn_arg_name_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
|
||||
fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
|
||||
|
||||
init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false);
|
||||
|
||||
for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++)
|
||||
{
|
||||
ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);
|
||||
ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.s_none.elements[fn_arg_index];
|
||||
ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index];
|
||||
ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name);
|
||||
init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true);
|
||||
fn_arg_name_val->data.x_struct.parent.id = ConstParentIdArray;
|
||||
@ -17593,15 +17599,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
|
||||
enum_field_array->special = ConstValSpecialStatic;
|
||||
enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count);
|
||||
enum_field_array->data.x_array.special = ConstArraySpecialNone;
|
||||
enum_field_array->data.x_array.s_none.parent.id = ConstParentIdNone;
|
||||
enum_field_array->data.x_array.s_none.elements = create_const_vals(enum_field_count);
|
||||
enum_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
|
||||
enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count);
|
||||
|
||||
init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false);
|
||||
|
||||
for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++)
|
||||
{
|
||||
TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index];
|
||||
ConstExprValue *enum_field_val = &enum_field_array->data.x_array.s_none.elements[enum_field_index];
|
||||
ConstExprValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index];
|
||||
make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type);
|
||||
enum_field_val->data.x_struct.parent.id = ConstParentIdArray;
|
||||
enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array;
|
||||
@ -17632,13 +17638,13 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
|
||||
error_array->special = ConstValSpecialStatic;
|
||||
error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count);
|
||||
error_array->data.x_array.special = ConstArraySpecialNone;
|
||||
error_array->data.x_array.s_none.parent.id = ConstParentIdNone;
|
||||
error_array->data.x_array.s_none.elements = create_const_vals(error_count);
|
||||
error_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
|
||||
error_array->data.x_array.data.s_none.elements = create_const_vals(error_count);
|
||||
|
||||
init_const_slice(ira->codegen, &fields[0], error_array, 0, error_count, false);
|
||||
for (uint32_t error_index = 0; error_index < error_count; error_index++) {
|
||||
ErrorTableEntry *error = type_entry->data.error_set.errors[error_index];
|
||||
ConstExprValue *error_val = &error_array->data.x_array.s_none.elements[error_index];
|
||||
ConstExprValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index];
|
||||
|
||||
error_val->special = ConstValSpecialStatic;
|
||||
error_val->type = type_info_error_type;
|
||||
@ -17727,8 +17733,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
|
||||
union_field_array->special = ConstValSpecialStatic;
|
||||
union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count);
|
||||
union_field_array->data.x_array.special = ConstArraySpecialNone;
|
||||
union_field_array->data.x_array.s_none.parent.id = ConstParentIdNone;
|
||||
union_field_array->data.x_array.s_none.elements = create_const_vals(union_field_count);
|
||||
union_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
|
||||
union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count);
|
||||
|
||||
init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false);
|
||||
|
||||
@ -17736,7 +17742,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
|
||||
|
||||
for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) {
|
||||
TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index];
|
||||
ConstExprValue *union_field_val = &union_field_array->data.x_array.s_none.elements[union_field_index];
|
||||
ConstExprValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index];
|
||||
|
||||
union_field_val->special = ConstValSpecialStatic;
|
||||
union_field_val->type = type_info_union_field_type;
|
||||
@ -17800,14 +17806,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
|
||||
struct_field_array->special = ConstValSpecialStatic;
|
||||
struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count);
|
||||
struct_field_array->data.x_array.special = ConstArraySpecialNone;
|
||||
struct_field_array->data.x_array.s_none.parent.id = ConstParentIdNone;
|
||||
struct_field_array->data.x_array.s_none.elements = create_const_vals(struct_field_count);
|
||||
struct_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
|
||||
struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count);
|
||||
|
||||
init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false);
|
||||
|
||||
for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) {
|
||||
TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index];
|
||||
ConstExprValue *struct_field_val = &struct_field_array->data.x_array.s_none.elements[struct_field_index];
|
||||
ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index];
|
||||
|
||||
struct_field_val->special = ConstValSpecialStatic;
|
||||
struct_field_val->type = type_info_struct_field_type;
|
||||
@ -17906,15 +17912,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
|
||||
fn_arg_array->special = ConstValSpecialStatic;
|
||||
fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count);
|
||||
fn_arg_array->data.x_array.special = ConstArraySpecialNone;
|
||||
fn_arg_array->data.x_array.s_none.parent.id = ConstParentIdNone;
|
||||
fn_arg_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count);
|
||||
fn_arg_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
|
||||
fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
|
||||
|
||||
init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false);
|
||||
|
||||
for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++)
|
||||
{
|
||||
FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index];
|
||||
ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.s_none.elements[fn_arg_index];
|
||||
ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index];
|
||||
|
||||
fn_arg_val->special = ConstValSpecialStatic;
|
||||
fn_arg_val->type = type_info_fn_arg_type;
|
||||
@ -18059,7 +18065,7 @@ static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCIm
|
||||
assert(node->type == NodeTypeFnCallExpr);
|
||||
AstNode *block_node = node->data.fn_call_expr.params.at(0);
|
||||
|
||||
ScopeCImport *cimport_scope = create_cimport_scope(node, instruction->base.scope);
|
||||
ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.scope);
|
||||
|
||||
// Execute the C import block like an inline function
|
||||
ZigType *void_type = ira->codegen->builtin_types.entry_void;
|
||||
@ -18072,7 +18078,7 @@ static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCIm
|
||||
find_libc_include_path(ira->codegen);
|
||||
|
||||
ImportTableEntry *child_import = allocate<ImportTableEntry>(1);
|
||||
child_import->decls_scope = create_decls_scope(node, nullptr, nullptr, child_import);
|
||||
child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import);
|
||||
child_import->c_import_node = node;
|
||||
child_import->package = new_anonymous_package();
|
||||
child_import->package->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package);
|
||||
@ -18826,7 +18832,7 @@ static ZigType *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemse
|
||||
{
|
||||
ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;
|
||||
expand_undef_array(ira->codegen, array_val);
|
||||
dest_elements = array_val->data.x_array.s_none.elements;
|
||||
dest_elements = array_val->data.x_array.data.s_none.elements;
|
||||
start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;
|
||||
bound_end = array_val->type->data.array.len;
|
||||
break;
|
||||
@ -18940,7 +18946,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp
|
||||
{
|
||||
ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;
|
||||
expand_undef_array(ira->codegen, array_val);
|
||||
dest_elements = array_val->data.x_array.s_none.elements;
|
||||
dest_elements = array_val->data.x_array.data.s_none.elements;
|
||||
dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;
|
||||
dest_end = array_val->type->data.array.len;
|
||||
break;
|
||||
@ -18976,7 +18982,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp
|
||||
{
|
||||
ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val;
|
||||
expand_undef_array(ira->codegen, array_val);
|
||||
src_elements = array_val->data.x_array.s_none.elements;
|
||||
src_elements = array_val->data.x_array.data.s_none.elements;
|
||||
src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index;
|
||||
src_end = array_val->type->data.array.len;
|
||||
break;
|
||||
@ -20282,9 +20288,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
|
||||
case ZigTypeIdArray:
|
||||
{
|
||||
size_t buf_i = 0;
|
||||
// TODO optimize the buf case
|
||||
expand_undef_array(codegen, val);
|
||||
for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) {
|
||||
ConstExprValue *elem = &val->data.x_array.s_none.elements[elem_i];
|
||||
ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i];
|
||||
buf_write_value_bytes(codegen, &buf[buf_i], elem);
|
||||
buf_i += type_size(codegen, elem->type);
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ comptime {
|
||||
_ = @import("cases/atomics.zig");
|
||||
_ = @import("cases/bitcast.zig");
|
||||
_ = @import("cases/bool.zig");
|
||||
_ = @import("cases/bugs/1076.zig");
|
||||
_ = @import("cases/bugs/1111.zig");
|
||||
_ = @import("cases/bugs/1277.zig");
|
||||
_ = @import("cases/bugs/1322.zig");
|
||||
|
||||
16
test/cases/bugs/1076.zig
Normal file
16
test/cases/bugs/1076.zig
Normal file
@ -0,0 +1,16 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "comptime code should not modify constant data" {
|
||||
testCastPtrOfArrayToSliceAndPtr();
|
||||
comptime testCastPtrOfArrayToSliceAndPtr();
|
||||
}
|
||||
|
||||
fn testCastPtrOfArrayToSliceAndPtr() void {
|
||||
var array = "aoeu";
|
||||
const x: [*]u8 = &array;
|
||||
x[0] += 1;
|
||||
assert(mem.eql(u8, array[0..], "boeu"));
|
||||
}
|
||||
|
||||
@ -400,7 +400,7 @@ test "single-item pointer of array to slice and to unknown length pointer" {
|
||||
}
|
||||
|
||||
fn testCastPtrOfArrayToSliceAndPtr() void {
|
||||
var array = "ao" ++ "eu"; // TODO https://github.com/ziglang/zig/issues/1076
|
||||
var array = "aoeu";
|
||||
const x: [*]u8 = &array;
|
||||
x[0] += 1;
|
||||
assert(mem.eql(u8, array[0..], "boeu"));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user