From 48de1a01a9bc5cdc2edda363681455078bae3e52 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 22 Oct 2021 13:14:19 +0100 Subject: [PATCH 01/14] Correct update propagation of type for ternary if expressions --- src/check_expr.cpp | 13 ++++++++++--- src/check_stmt.cpp | 2 ++ src/llvm_backend_const.cpp | 2 +- src/llvm_backend_expr.cpp | 28 +++++++++++++++++----------- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 513144f11..04ba28b60 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -829,7 +829,7 @@ void check_assignment(CheckerContext *c, Operand *operand, Type *type, String co operand->mode = Addressing_Invalid; } - + convert_to_typed(c, operand, type); return; } @@ -837,6 +837,8 @@ void check_assignment(CheckerContext *c, Operand *operand, Type *type, String co if (operand->mode == Addressing_Type && is_type_typeid(type)) { add_type_info_type(c, operand->type); add_type_and_value(c->info, operand->expr, Addressing_Value, type, exact_value_typeid(operand->type)); + } else { + convert_to_typed(c, operand, type); } } else { gbString expr_str = expr_to_string(operand->expr); @@ -3014,11 +3016,15 @@ void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) if (type != nullptr && type != t_invalid) { if (e->tav.type == nullptr || e->tav.type == t_invalid) { add_type_and_value(c->info, e, e->tav.mode, type ? type : e->tav.type, e->tav.value); + if (e->kind == Ast_TernaryIfExpr) { + goto propagate; + } } } return; } +propagate:; switch (e->kind) { case_ast_node(ue, UnaryExpr, e); if (old->value.kind != ExactValue_Invalid) { @@ -6742,13 +6748,14 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type type = y.type; } - o->type = type; + o->type = x.type; o->mode = Addressing_Value; + o->expr = node; if (type_hint != nullptr && is_type_untyped(type)) { if (check_cast_internal(c, &x, type_hint) && check_cast_internal(c, &y, type_hint)) { + convert_to_typed(c, o, type_hint); update_untyped_expr_type(c, node, type_hint, !is_type_untyped(type_hint)); - o->type = type_hint; } } case_end; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 103ffa071..4dbc76578 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1728,6 +1728,8 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { Entity *e = pt->results->Tuple.variables[i]; Operand *o = &operands[i]; check_assignment(ctx, o, e->type, str_lit("return statement")); + convert_to_typed(ctx, o, e->type); + if (is_type_untyped(o->type)) { update_untyped_expr_type(ctx, o->expr, e->type, true); } diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 68050e0ce..18b6ee6f6 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -329,7 +329,7 @@ LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, BigInt const * debug_print_big_int(a); gb_printf_err("%s -> %tu\n", type_to_string(original_type), sz);; } - GB_ASSERT_MSG(sz >= max_count, "max_count: %tu, sz: %tu, written: %tu", max_count, sz, written); + GB_ASSERT_MSG(sz >= max_count, "max_count: %tu, sz: %tu, written: %tu, type %s", max_count, sz, written, type_to_string(original_type)); GB_ASSERT(gb_size_of(rop64) >= sz); mp_err err = mp_pack(rop, sz, &written, diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 763afacc2..caeae2fb0 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -762,6 +762,12 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { case Token_Xor: case Token_AndNot: { Type *type = default_type(tv.type); + if (is_type_typed(be->left->tav.type) && is_type_untyped(be->right->tav.type)) { + be->right->tav.type = be->left->tav.type; + } else if (is_type_untyped(be->left->tav.type) && is_type_typed(be->right->tav.type)) { + be->left->tav.type = type_of_expr(be->right); + } + lbValue left = lb_build_expr(p, be->left); lbValue right = lb_build_expr(p, be->right); return lb_emit_arith(p, be->op.kind, left, right, type); @@ -2247,17 +2253,18 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { TokenPos expr_pos = ast_token(expr).pos; TypeAndValue tv = type_and_value_of_expr(expr); + Type *type = type_of_expr(expr); GB_ASSERT_MSG(tv.mode != Addressing_Invalid, "invalid expression '%s' (tv.mode = %d, tv.type = %s) @ %s\n Current Proc: %.*s : %s", expr_to_string(expr), tv.mode, type_to_string(tv.type), token_pos_to_string(expr_pos), LIT(p->name), type_to_string(p->type)); if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): The commented out code below is just for debug purposes only // GB_ASSERT_MSG(!is_type_untyped(tv.type), "%s @ %s\n%s", type_to_string(tv.type), token_pos_to_string(expr_pos), expr_to_string(expr)); - // if (is_type_untyped(tv.type)) { + // if (is_type_untyped(type)) { // gb_printf_err("%s %s\n", token_pos_to_string(expr_pos), expr_to_string(expr)); // } // NOTE(bill): Short on constant values - return lb_const_value(p->module, tv.type, tv.value); + return lb_const_value(p->module, type, tv.value); } #if 0 @@ -2288,12 +2295,12 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { case_ast_node(u, Undef, expr) lbValue res = {}; - if (is_type_untyped(tv.type)) { + if (is_type_untyped(type)) { res.value = nullptr; res.type = t_untyped_undef; } else { - res.value = LLVMGetUndef(lb_type(m, tv.type)); - res.type = tv.type; + res.value = LLVMGetUndef(lb_type(m, type)); + res.type = type; } return res; case_end; @@ -2334,7 +2341,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { TypeAndValue tav = type_and_value_of_expr(expr); GB_ASSERT(tav.mode == Addressing_Constant); - return lb_const_value(p->module, tv.type, tv.value); + return lb_const_value(p->module, type, tv.value); case_end; case_ast_node(se, SelectorCallExpr, expr); @@ -2407,7 +2414,6 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { case_ast_node(ta, TypeAssertion, expr); TokenPos pos = ast_token(expr).pos; - Type *type = tv.type; lbValue e = lb_build_expr(p, ta->expr); Type *t = type_deref(e.type); if (is_type_union(t)) { @@ -2427,16 +2433,16 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { lbValue e = lb_build_expr(p, tc->expr); switch (tc->token.kind) { case Token_cast: - return lb_emit_conv(p, e, tv.type); + return lb_emit_conv(p, e, type); case Token_transmute: - return lb_emit_transmute(p, e, tv.type); + return lb_emit_transmute(p, e, type); } GB_PANIC("Invalid AST TypeCast"); case_end; case_ast_node(ac, AutoCast, expr); lbValue value = lb_build_expr(p, ac->expr); - return lb_emit_conv(p, value, tv.type); + return lb_emit_conv(p, value, type); case_end; case_ast_node(ue, UnaryExpr, expr); @@ -2446,7 +2452,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { default: { lbValue v = lb_build_expr(p, ue->expr); - return lb_emit_unary_arith(p, ue->op.kind, v, tv.type); + return lb_emit_unary_arith(p, ue->op.kind, v, type); } } case_end; From 28af376d103da1b7820032de0b6d8fc6ca9d6d3a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 22 Oct 2021 13:17:49 +0100 Subject: [PATCH 02/14] Quick fix --- src/check_expr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 04ba28b60..a3554f3ea 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3017,14 +3017,14 @@ void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) if (e->tav.type == nullptr || e->tav.type == t_invalid) { add_type_and_value(c->info, e, e->tav.mode, type ? type : e->tav.type, e->tav.value); if (e->kind == Ast_TernaryIfExpr) { - goto propagate; + update_untyped_expr_type(c, e->TernaryIfExpr.x, type, final); + update_untyped_expr_type(c, e->TernaryIfExpr.y, type, final); } } } return; } -propagate:; switch (e->kind) { case_ast_node(ue, UnaryExpr, e); if (old->value.kind != ExactValue_Invalid) { From ef73a284e3e438a25a4e329d59057cfa8cddf44c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 22 Oct 2021 14:12:48 +0100 Subject: [PATCH 03/14] Fix check_remove_expr_info --- src/checker.cpp | 9 ++++++++- src/llvm_backend_expr.cpp | 4 ++-- src/map.cpp | 40 +++++++++++++++++++++------------------ src/parser.hpp | 2 +- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/checker.cpp b/src/checker.cpp index d3c0080de..ec20d45d6 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1111,9 +1111,15 @@ void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type void check_remove_expr_info(CheckerContext *c, Ast *e) { if (c->untyped != nullptr) { map_remove(c->untyped, hash_pointer(e)); + if (map_get(c->untyped, hash_pointer(e)) != nullptr) { + map_remove(c->untyped, hash_pointer(e)); + GB_ASSERT(map_get(c->untyped, hash_pointer(e)) == nullptr); + } } else { + auto *untyped = &c->info->global_untyped; mutex_lock(&c->info->global_untyped_mutex); - map_remove(&c->info->global_untyped, hash_pointer(e)); + map_remove(untyped, hash_pointer(e)); + GB_ASSERT(map_get(untyped, hash_pointer(e)) == nullptr); mutex_unlock(&c->info->global_untyped_mutex); } } @@ -1191,6 +1197,7 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty prev_expr = expr; expr->tav.mode = mode; expr->tav.type = type; + if (mode == Addressing_Constant || mode == Addressing_Invalid) { expr->tav.value = value; } else if (mode == Addressing_Value && is_type_typeid(type)) { diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index caeae2fb0..6ad0e1191 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2258,9 +2258,9 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): The commented out code below is just for debug purposes only - // GB_ASSERT_MSG(!is_type_untyped(tv.type), "%s @ %s\n%s", type_to_string(tv.type), token_pos_to_string(expr_pos), expr_to_string(expr)); // if (is_type_untyped(type)) { - // gb_printf_err("%s %s\n", token_pos_to_string(expr_pos), expr_to_string(expr)); + // gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav.type), expr); + // GB_PANIC("%s\n", type_to_string(tv.type)); // } // NOTE(bill): Short on constant values diff --git a/src/map.cpp b/src/map.cpp index 55eb4fbce..3a34764bf 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -114,16 +114,17 @@ gb_internal isize map__add_entry(Map *h, HashKey const &key) { template gb_internal MapFindResult map__find(Map *h, HashKey const &key) { MapFindResult fr = {-1, -1, -1}; - if (h->hashes.count > 0) { - fr.hash_index = key.key & (h->hashes.count-1); - fr.entry_index = h->hashes.data[fr.hash_index]; - while (fr.entry_index >= 0) { - if (hash_key_equal(h->entries.data[fr.entry_index].key, key)) { - return fr; - } - fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries.data[fr.entry_index].next; + if (h->hashes.count == 0) { + return fr; + } + fr.hash_index = key.key & (h->hashes.count-1); + fr.entry_index = h->hashes.data[fr.hash_index]; + while (fr.entry_index >= 0) { + if (hash_key_equal(h->entries.data[fr.entry_index].key, key)) { + return fr; } + fr.entry_prev = fr.entry_index; + fr.entry_index = h->entries.data[fr.entry_index].next; } return fr; } @@ -131,16 +132,17 @@ gb_internal MapFindResult map__find(Map *h, HashKey const &key) { template gb_internal MapFindResult map__find_from_entry(Map *h, MapEntry *e) { MapFindResult fr = {-1, -1, -1}; - if (h->hashes.count > 0) { - fr.hash_index = e->key.key & (h->hashes.count-1); - fr.entry_index = h->hashes.data[fr.hash_index]; - while (fr.entry_index >= 0) { - if (&h->entries.data[fr.entry_index] == e) { - return fr; - } - fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries.data[fr.entry_index].next; + if (h->hashes.count == 0) { + return fr; + } + fr.hash_index = e->key.key & (h->hashes.count-1); + fr.entry_index = h->hashes.data[fr.hash_index]; + while (fr.entry_index >= 0) { + if (&h->entries.data[fr.entry_index] == e) { + return fr; } + fr.entry_prev = fr.entry_index; + fr.entry_index = h->entries.data[fr.entry_index].next; } return fr; } @@ -246,6 +248,8 @@ void map__erase(Map *h, MapFindResult const &fr) { return; } h->entries.data[fr.entry_index] = h->entries.data[h->entries.count-1]; + array_pop(&h->entries); + last = map__find(h, h->entries.data[fr.entry_index].key); if (last.entry_prev >= 0) { h->entries.data[last.entry_prev].next = fr.entry_index; diff --git a/src/parser.hpp b/src/parser.hpp index f1779bdbc..8acc3f419 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -28,9 +28,9 @@ enum AddressingMode : u8 { }; struct TypeAndValue { + Type * type; AddressingMode mode; bool is_lhs; // Debug info - Type * type; ExactValue value; }; From c9effb9b9f6dd0400e2396fd2aa6a97e06a14638 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 22 Oct 2021 14:37:27 +0100 Subject: [PATCH 04/14] Correct ternary if expression type determination --- src/check_expr.cpp | 23 ++++++++++++++--------- src/check_stmt.cpp | 2 -- src/checker.cpp | 12 +++++++----- src/llvm_backend_expr.cpp | 6 ------ 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index a3554f3ea..275210c6c 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -837,8 +837,6 @@ void check_assignment(CheckerContext *c, Operand *operand, Type *type, String co if (operand->mode == Addressing_Type && is_type_typeid(type)) { add_type_info_type(c, operand->type); add_type_and_value(c->info, operand->expr, Addressing_Value, type, exact_value_typeid(operand->type)); - } else { - convert_to_typed(c, operand, type); } } else { gbString expr_str = expr_to_string(operand->expr); @@ -3226,9 +3224,9 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { case Basic_UntypedNil: if (is_type_any(target_type)) { - target_type = t_untyped_nil; + // target_type = t_untyped_nil; } else if (is_type_cstring(target_type)) { - target_type = t_untyped_nil; + // target_type = t_untyped_nil; } else if (!type_has_nil(target_type)) { operand->mode = Addressing_Invalid; convert_untyped_error(c, operand, target_type); @@ -3376,6 +3374,14 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { } break; } + + if (is_type_any(target_type) && is_type_untyped(operand->type)) { + if (is_type_untyped_nil(operand->type) && is_type_untyped_undef(operand->type)) { + + } else { + target_type = default_type(operand->type); + } + } update_untyped_expr_type(c, operand->expr, target_type, true); operand->type = target_type; @@ -6743,15 +6749,14 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type return kind; } - Type *type = x.type; - if (is_type_untyped_nil(type) || is_type_untyped_undef(type)) { - type = y.type; + o->type = x.type; + if (is_type_untyped_nil(o->type) || is_type_untyped_undef(o->type)) { + o->type = y.type; } - o->type = x.type; o->mode = Addressing_Value; o->expr = node; - if (type_hint != nullptr && is_type_untyped(type)) { + if (type_hint != nullptr && is_type_untyped(o->type)) { if (check_cast_internal(c, &x, type_hint) && check_cast_internal(c, &y, type_hint)) { convert_to_typed(c, o, type_hint); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 4dbc76578..103ffa071 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1728,8 +1728,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { Entity *e = pt->results->Tuple.variables[i]; Operand *o = &operands[i]; check_assignment(ctx, o, e->type, str_lit("return statement")); - convert_to_typed(ctx, o, e->type); - if (is_type_untyped(o->type)) { update_untyped_expr_type(ctx, o->expr, e->type, true); } diff --git a/src/checker.cpp b/src/checker.cpp index ec20d45d6..b1b148a84 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1111,10 +1111,7 @@ void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type void check_remove_expr_info(CheckerContext *c, Ast *e) { if (c->untyped != nullptr) { map_remove(c->untyped, hash_pointer(e)); - if (map_get(c->untyped, hash_pointer(e)) != nullptr) { - map_remove(c->untyped, hash_pointer(e)); - GB_ASSERT(map_get(c->untyped, hash_pointer(e)) == nullptr); - } + GB_ASSERT(map_get(c->untyped, hash_pointer(e)) == nullptr); } else { auto *untyped = &c->info->global_untyped; mutex_lock(&c->info->global_untyped_mutex); @@ -1196,7 +1193,12 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty while (prev_expr != expr) { prev_expr = expr; expr->tav.mode = mode; - expr->tav.type = type; + if (type != nullptr && expr->tav.type != nullptr && + is_type_any(type) && is_type_untyped(expr->tav.type)) { + // ignore + } else { + expr->tav.type = type; + } if (mode == Addressing_Constant || mode == Addressing_Invalid) { expr->tav.value = value; diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 6ad0e1191..214da9e10 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -762,12 +762,6 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { case Token_Xor: case Token_AndNot: { Type *type = default_type(tv.type); - if (is_type_typed(be->left->tav.type) && is_type_untyped(be->right->tav.type)) { - be->right->tav.type = be->left->tav.type; - } else if (is_type_untyped(be->left->tav.type) && is_type_typed(be->right->tav.type)) { - be->left->tav.type = type_of_expr(be->right); - } - lbValue left = lb_build_expr(p, be->left); lbValue right = lb_build_expr(p, be->right); return lb_emit_arith(p, be->op.kind, left, right, type); From 7375074d2d9a459535fa35cafe4d80a51474ee81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Hjortsh=C3=B8j?= Date: Fri, 22 Oct 2021 22:34:42 +0200 Subject: [PATCH 05/14] Update nightly.yml --- .github/workflows/nightly.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 9ddb8ee83..3dba6f28f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -127,16 +127,23 @@ jobs: BUCKET: ${{ secrets.B2_BUCKET }} DAYS_TO_KEEP: ${{ secrets.B2_DAYS_TO_KEEP }} run: | + echo Authorizing B2 account b2 authorize-account "$APPID" "$APPKEY" - + + echo Uploading artifcates to B2 chmod +x ./ci/upload_create_nightly.sh ./ci/upload_create_nightly.sh "$BUCKET" windows-amd64 windows_artifacts/ ./ci/upload_create_nightly.sh "$BUCKET" ubuntu-amd64 ubuntu_artifacts/ ./ci/upload_create_nightly.sh "$BUCKET" macos-amd64 macos_artifacts/ + echo Deleting old artifacts in B2 python3 ci/delete_old_binaries.py "$BUCKET" "$DAYS_TO_KEEP" + echo Creating nightly.json python3 ci/create_nightly_json.py "$BUCKET" > nightly.json + + echo Uploading nightly.json b2 upload-file "$BUCKET" nightly.json nightly.json + echo Clear B2 account info b2 clear-account From 7218a68e894d765a6b30ed48f64d91740ce2b23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Hjortsh=C3=B8j?= Date: Fri, 22 Oct 2021 22:42:20 +0200 Subject: [PATCH 06/14] Update nightly.yml Downgrading python version in nightly to use same version as local --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 3dba6f28f..2b33c45a8 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -93,7 +93,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-python@v2 with: - python-version: '3.x' + python-version: '3.8.x' - name: Install B2 CLI shell: bash From 3323c2730f719035172330362aed3d9c3f5cadf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <49562770+awwdev@users.noreply.github.com> Date: Sat, 23 Oct 2021 12:24:53 +0200 Subject: [PATCH 07/14] memleak fix on destroy_multi_logger() data.loggers were never deleted --- core/log/multi_logger.odin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/log/multi_logger.odin b/core/log/multi_logger.odin index b4cd8b1a1..55c0f1436 100644 --- a/core/log/multi_logger.odin +++ b/core/log/multi_logger.odin @@ -13,6 +13,8 @@ create_multi_logger :: proc(logs: ..Logger) -> Logger { } destroy_multi_logger :: proc(log : ^Logger) { + data := (^Multi_Logger_Data)(log.data) + delete(data.loggers) free(log.data) log^ = nil_logger() } From faa9df87359e9fb24423e8d14f3f1f4e36a946f4 Mon Sep 17 00:00:00 2001 From: awwdev Date: Sat, 23 Oct 2021 12:46:09 +0200 Subject: [PATCH 08/14] changed KeyCode to Keycode --- vendor/sdl2/sdl_keyboard.odin | 10 +++++----- vendor/sdl2/sdl_keycode.odin | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/vendor/sdl2/sdl_keyboard.odin b/vendor/sdl2/sdl_keyboard.odin index 507b549cb..86112863a 100644 --- a/vendor/sdl2/sdl_keyboard.odin +++ b/vendor/sdl2/sdl_keyboard.odin @@ -9,7 +9,7 @@ when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } Keysym :: struct { scancode: Scancode, /**< SDL physical key code - see ::SDL_Scancode for details */ - sym: KeyCode, /**< SDL virtual key code - see ::SDL_KeyCode for details */ + sym: Keycode, /**< SDL virtual key code - see ::SDL_Keycode for details */ mod: Keymod, /**< current key modifiers */ unused: u32, } @@ -19,12 +19,12 @@ Keysym :: struct { foreign lib { GetKeyboardFocus :: proc() -> ^Window --- GetKeyboardState :: proc(numkeys: ^c.int) -> [^]u8 --- - GetKeyFromScancode :: proc(scancode: Scancode) -> KeyCode --- - GetScancodeFromKey :: proc(key: KeyCode) -> Scancode --- + GetKeyFromScancode :: proc(scancode: Scancode) -> Keycode --- + GetScancodeFromKey :: proc(key: Keycode) -> Scancode --- GetScancodeName :: proc(scancode: Scancode) -> cstring --- GetScancodeFromName :: proc(name: cstring) -> Scancode --- - GetKeyName :: proc(key: KeyCode) -> cstring --- - GetKeyFromName :: proc(name: cstring) -> KeyCode --- + GetKeyName :: proc(key: Keycode) -> cstring --- + GetKeyFromName :: proc(name: cstring) -> Keycode --- StartTextInput :: proc() --- IsTextInputActive :: proc() -> bool --- StopTextInput :: proc() --- diff --git a/vendor/sdl2/sdl_keycode.odin b/vendor/sdl2/sdl_keycode.odin index 2b79d0e47..73637f072 100644 --- a/vendor/sdl2/sdl_keycode.odin +++ b/vendor/sdl2/sdl_keycode.odin @@ -2,11 +2,11 @@ package sdl2 SCANCODE_MASK :: 1<<30 -SCANCODE_TO_KEYCODE :: #force_inline proc "c" (X: Scancode) -> KeyCode { - return KeyCode(i32(X) | SCANCODE_MASK) +SCANCODE_TO_KEYCODE :: #force_inline proc "c" (X: Scancode) -> Keycode { + return Keycode(i32(X) | SCANCODE_MASK) } -KeyCode :: enum i32 { +Keycode :: enum i32 { UNKNOWN = 0, RETURN = '\r', From 71932da7e37bfd13ddbbbbc96980e0274c44fbdf Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Oct 2021 16:52:43 +0100 Subject: [PATCH 09/14] Add `intrinsics.unaligned_store` `intrinsics.unaligned_load` --- src/check_builtin.cpp | 4 + src/checker_builtin_procs.hpp | 6 ++ src/llvm_backend_proc.cpp | 138 ++++++++++++++++++++++------------ 3 files changed, 98 insertions(+), 50 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index a04302d01..a07c1f267 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -2567,6 +2567,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_volatile_store: /*fallthrough*/ + case BuiltinProc_unaligned_store: + /*fallthrough*/ case BuiltinProc_atomic_store: case BuiltinProc_atomic_store_rel: case BuiltinProc_atomic_store_relaxed: @@ -2588,6 +2590,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_volatile_load: /*fallthrough*/ + case BuiltinProc_unaligned_load: + /*fallthrough*/ case BuiltinProc_atomic_load: case BuiltinProc_atomic_load_acq: case BuiltinProc_atomic_load_relaxed: diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index 8991d2d5c..e9eb76b0b 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -72,6 +72,9 @@ enum BuiltinProcId { BuiltinProc_volatile_store, BuiltinProc_volatile_load, + BuiltinProc_unaligned_store, + BuiltinProc_unaligned_load, + BuiltinProc_prefetch_read_instruction, BuiltinProc_prefetch_read_data, BuiltinProc_prefetch_write_instruction, @@ -314,6 +317,9 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("volatile_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("volatile_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("unaligned_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + {STR_LIT("unaligned_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("prefetch_read_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("prefetch_read_data"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("prefetch_write_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 222161164..e577dc248 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1,3 +1,62 @@ +void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false) { + dst = lb_emit_conv(p, dst, t_rawptr); + src = lb_emit_conv(p, src, t_rawptr); + len = lb_emit_conv(p, len, t_int); + + char const *name = "llvm.memmove"; + if (LLVMIsConstant(len.value)) { + i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value); + if (const_len <= 4*build_context.word_size) { + name = "llvm.memmove.inline"; + } + } + + LLVMTypeRef types[3] = { + lb_type(p->module, t_rawptr), + lb_type(p->module, t_rawptr), + lb_type(p->module, t_int) + }; + unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2])); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); + + LLVMValueRef args[4] = {}; + args[0] = dst.value; + args[1] = src.value; + args[2] = len.value; + args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile); + LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); +} +void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false) { + dst = lb_emit_conv(p, dst, t_rawptr); + src = lb_emit_conv(p, src, t_rawptr); + len = lb_emit_conv(p, len, t_int); + + char const *name = "llvm.memcpy"; + if (LLVMIsConstant(len.value)) { + i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value); + if (const_len <= 4*build_context.word_size) { + name = "llvm.memcpy.inline"; + } + } + + LLVMTypeRef types[3] = { + lb_type(p->module, t_rawptr), + lb_type(p->module, t_rawptr), + lb_type(p->module, t_int) + }; + unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2])); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); + + LLVMValueRef args[4] = {}; + args[0] = dst.value; + args[1] = src.value; + args[2] = len.value; + args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile); + LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); +} + lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) { GB_ASSERT(entity != nullptr); @@ -1431,61 +1490,21 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } case BuiltinProc_mem_copy: + { + lbValue dst = lb_build_expr(p, ce->args[0]); + lbValue src = lb_build_expr(p, ce->args[1]); + lbValue len = lb_build_expr(p, ce->args[2]); + + lb_mem_copy_overlapping(p, dst, src, len, false); + return {}; + } case BuiltinProc_mem_copy_non_overlapping: { lbValue dst = lb_build_expr(p, ce->args[0]); lbValue src = lb_build_expr(p, ce->args[1]); lbValue len = lb_build_expr(p, ce->args[2]); - dst = lb_emit_conv(p, dst, t_rawptr); - src = lb_emit_conv(p, src, t_rawptr); - len = lb_emit_conv(p, len, t_int); - - bool is_inlinable = false; - - if (ce->args[2]->tav.mode == Addressing_Constant) { - ExactValue ev = exact_value_to_integer(ce->args[2]->tav.value); - i64 const_len = exact_value_to_i64(ev); - // TODO(bill): Determine when it is better to do the `*.inline` versions - if (const_len <= 4*build_context.word_size) { - is_inlinable = true; - } - } - - char const *name = nullptr; - switch (id) { - case BuiltinProc_mem_copy: - if (is_inlinable) { - name = "llvm.memmove.inline"; - } else { - name = "llvm.memmove"; - } - break; - case BuiltinProc_mem_copy_non_overlapping: - if (is_inlinable) { - name = "llvm.memcpy.line"; - } else { - name = "llvm.memcpy"; - } - break; - } - - LLVMTypeRef types[3] = { - lb_type(p->module, t_rawptr), - lb_type(p->module, t_rawptr), - lb_type(p->module, t_int) - }; - unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); - GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2])); - LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); - - LLVMValueRef args[4] = {}; - args[0] = dst.value; - args[1] = src.value; - args[2] = len.value; - args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, false); // is_volatile parameter - - LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); - + + lb_mem_copy_non_overlapping(p, dst, src, len, false); return {}; } @@ -1591,6 +1610,25 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, res.type = type_deref(dst.type); return res; } + + case BuiltinProc_unaligned_store: + { + lbValue dst = lb_build_expr(p, ce->args[0]); + lbValue src = lb_build_expr(p, ce->args[1]); + src = lb_address_from_load_or_generate_local(p, src); + Type *t = type_deref(dst.type); + lb_mem_copy_non_overlapping(p, dst, src, lb_const_int(p->module, t_int, type_size_of(t)), false); + return {}; + } + + case BuiltinProc_unaligned_load: + { + lbValue src = lb_build_expr(p, ce->args[0]); + Type *t = type_deref(src.type); + lbAddr dst = lb_add_local_generated(p, t, false); + lb_mem_copy_non_overlapping(p, dst.addr, src, lb_const_int(p->module, t_int, type_size_of(t)), false); + return lb_addr_load(p, dst); + } case BuiltinProc_atomic_add: case BuiltinProc_atomic_add_acq: From 18ed444a63595fd418187b82105b5c0f5b6a1857 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Oct 2021 17:10:12 +0100 Subject: [PATCH 10/14] Strip semicolons --- core/runtime/default_allocators_nil.odin | 4 ++-- core/runtime/os_specific_freestanding.odin | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/runtime/default_allocators_nil.odin b/core/runtime/default_allocators_nil.odin index 443f41a51..5100bc517 100644 --- a/core/runtime/default_allocators_nil.odin +++ b/core/runtime/default_allocators_nil.odin @@ -6,12 +6,12 @@ package runtime default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) { - return nil, .None; + return nil, .None } default_allocator :: proc() -> Allocator { return Allocator{ procedure = default_allocator_proc, data = nil, - }; + } } diff --git a/core/runtime/os_specific_freestanding.odin b/core/runtime/os_specific_freestanding.odin index 15323f763..a6d04cefb 100644 --- a/core/runtime/os_specific_freestanding.odin +++ b/core/runtime/os_specific_freestanding.odin @@ -3,5 +3,5 @@ package runtime // TODO(bill): reimplement `os.write` _os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { - return 0, -1; + return 0, -1 } From fba20c9bd310ade9c87900c6f84a49ce1704f0a6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Oct 2021 17:10:30 +0100 Subject: [PATCH 11/14] Improve `runtime.string_eq` --- core/runtime/internal.odin | 73 +++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 16930185e..4f3488eb7 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -258,15 +258,72 @@ memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int #no_bounds_ return 0 } -string_eq :: proc "contextless" (a, b: string) -> bool { - x := transmute(Raw_String)a - y := transmute(Raw_String)b +string_eq :: proc "contextless" (lhs, rhs: string) -> bool { + x := transmute(Raw_String)lhs + y := transmute(Raw_String)rhs switch { - case x.len != y.len: return false - case x.len == 0: return true - case x.data == y.data: return true + case x.len != y.len: return false + case x.len == 0: return true + case x.data == y.data: return true + } + + a, b := x.data, y.data + length := uint(x.len) + + when size_of(uint) == 8 { + if word_length := length >> 3; word_length != 0 { + for i in 0..> 2; word_length != 0 { + for i in 0.. int { @@ -708,7 +765,7 @@ floattidf :: proc "c" (a: i128) -> f64 { a += 1 a >>= 2 - if a & (1 << DBL_MANT_DIG) != 0 { + if a & (i128(1) << DBL_MANT_DIG) != 0 { a >>= 1 e += 1 } From d54b708ba817c308c3f3a02cf06975617a6757da Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Oct 2021 17:18:40 +0100 Subject: [PATCH 12/14] Unify `memory_equal` and `string_eq` --- core/runtime/internal.odin | 131 +++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 4f3488eb7..96944c7f2 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -177,8 +177,70 @@ mem_resize :: #force_inline proc(ptr: rawptr, old_size, new_size: int, alignment new_ptr = raw_data(new_data) return } -memory_equal :: proc "contextless" (a, b: rawptr, n: int) -> bool { - return memory_compare(a, b, n) == 0 +memory_equal :: proc "contextless" (x, y: rawptr, n: int) -> bool { + switch { + case n == 0: return true + case x == y: return true + } + + a, b := ([^]byte)(x), ([^]byte)(y) + length := uint(n) + + when size_of(uint) == 8 { + if word_length := length >> 3; word_length != 0 { + for i in 0..> 2; word_length != 0 { + for i in 0.. int #no_bounds_check { switch { @@ -261,69 +323,10 @@ memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int #no_bounds_ string_eq :: proc "contextless" (lhs, rhs: string) -> bool { x := transmute(Raw_String)lhs y := transmute(Raw_String)rhs - switch { - case x.len != y.len: return false - case x.len == 0: return true - case x.data == y.data: return true - } - - a, b := x.data, y.data - length := uint(x.len) - - when size_of(uint) == 8 { - if word_length := length >> 3; word_length != 0 { - for i in 0..> 2; word_length != 0 { - for i in 0.. int { From 2a50f9c8d410c88632f28bb8cb1325beb284d1c3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Oct 2021 17:41:11 +0100 Subject: [PATCH 13/14] Rename `-ignore-lazy` to `-internal-ignore-lazy` --- src/main.cpp | 9 ++++++--- src/parser.cpp | 3 +-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index cdc6468ab..8c6fb90af 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -632,7 +632,9 @@ enum BuildFlagKind { BuildFlag_IgnoreWarnings, BuildFlag_WarningsAsErrors, BuildFlag_VerboseErrors, - BuildFlag_IgnoreLazy, // internal use only + + // internal use only + BuildFlag_InternalIgnoreLazy, #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, @@ -779,7 +781,8 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_IgnoreWarnings, str_lit("ignore-warnings"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_WarningsAsErrors, str_lit("warnings-as-errors"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_VerboseErrors, str_lit("verbose-errors"), BuildFlagParam_None, Command_all); - add_flag(&build_flags, BuildFlag_IgnoreLazy, str_lit("ignore-lazy"), BuildFlagParam_None, Command_all); + + add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); #if defined(GB_SYSTEM_WINDOWS) add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build); @@ -1393,7 +1396,7 @@ bool parse_build_flags(Array args) { build_context.show_error_line = true; break; - case BuildFlag_IgnoreLazy: + case BuildFlag_InternalIgnoreLazy: build_context.ignore_lazy = true; break; diff --git a/src/parser.cpp b/src/parser.cpp index 716986b5d..ad025e145 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5372,8 +5372,7 @@ bool parse_file(Parser *p, AstFile *f) { // Ignore } else if (f->flags & AstFile_IsTest) { // Ignore - } else if (build_context.command_kind == Command_doc && - f->pkg->kind == Package_Init) { + } else if (f->pkg->kind == Package_Init && build_context.command_kind == Command_doc) { // Ignore } else { f->flags |= AstFile_IsLazy; From 06f47621442973a664b5928bb20295f4b7b56196 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Oct 2021 19:22:08 +0100 Subject: [PATCH 14/14] Allow parsing for `[^]T{}` to improve error messages --- src/parser.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/parser.cpp b/src/parser.cpp index ad025e145..7de26893e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2526,6 +2526,9 @@ bool is_literal_type(Ast *node) { case Ast_BitSetType: case Ast_CallExpr: return true; + case Ast_MultiPointerType: + // For better error messages + return true; } return false; }