Merge branch 'master' into new-matrix-type

This commit is contained in:
gingerBill
2021-10-23 19:24:47 +01:00
18 changed files with 270 additions and 123 deletions
+9 -2
View File
@@ -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
@@ -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
+2
View File
@@ -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()
}
+2 -2
View File
@@ -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,
};
}
}
+71 -11
View File
@@ -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..<word_length {
if intrinsics.unaligned_load((^u64)(a)) != intrinsics.unaligned_load((^u64)(b)) {
return false
}
a = a[size_of(u64):]
b = b[size_of(u64):]
}
}
if length & 4 != 0 {
if intrinsics.unaligned_load((^u32)(a)) != intrinsics.unaligned_load((^u32)(b)) {
return false
}
a = a[size_of(u32):]
b = b[size_of(u32):]
}
if length & 2 != 0 {
if intrinsics.unaligned_load((^u16)(a)) != intrinsics.unaligned_load((^u16)(b)) {
return false
}
a = a[size_of(u16):]
b = b[size_of(u16):]
}
if length & 1 != 0 && a[0] != b[0] {
return false
}
return true
} else {
if word_length := length >> 2; word_length != 0 {
for i in 0..<word_length {
if intrinsics.unaligned_load((^u32)(a)) != intrinsics.unaligned_load((^u32)(b)) {
return false
}
a = a[size_of(u32):]
b = b[size_of(u32):]
}
}
length &= 3
if length != 0 {
for i in 0..<length {
if a[i] != b[i] {
return false
}
}
}
return true
}
}
memory_compare :: proc "contextless" (a, b: rawptr, n: int) -> int #no_bounds_check {
switch {
@@ -258,15 +320,13 @@ 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
switch {
case x.len != y.len: return false
case x.len == 0: return true
case x.data == y.data: return true
string_eq :: proc "contextless" (lhs, rhs: string) -> bool {
x := transmute(Raw_String)lhs
y := transmute(Raw_String)rhs
if x.len != y.len {
return false
}
return string_cmp(a, b) == 0
return #force_inline memory_equal(x.data, y.data, x.len)
}
string_cmp :: proc "contextless" (a, b: string) -> int {
@@ -708,7 +768,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
}
+1 -1
View File
@@ -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
}
+4
View File
@@ -2749,6 +2749,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:
@@ -2770,6 +2772,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:
+21 -9
View File
@@ -837,7 +837,7 @@ void check_assignment(CheckerContext *c, Operand *operand, Type *type, String co
operand->mode = Addressing_Invalid;
}
convert_to_typed(c, operand, type);
return;
}
@@ -3208,6 +3208,10 @@ 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) {
update_untyped_expr_type(c, e->TernaryIfExpr.x, type, final);
update_untyped_expr_type(c, e->TernaryIfExpr.y, type, final);
}
}
}
return;
@@ -3414,9 +3418,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);
@@ -3587,6 +3591,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;
@@ -7030,18 +7042,18 @@ 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 = type;
o->mode = Addressing_Value;
if (type_hint != nullptr && is_type_untyped(type)) {
o->expr = node;
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);
update_untyped_expr_type(c, node, type_hint, !is_type_untyped(type_hint));
o->type = type_hint;
}
}
case_end;
+11 -2
View File
@@ -1111,9 +1111,12 @@ 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));
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);
}
}
@@ -1190,7 +1193,13 @@ 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;
} else if (mode == Addressing_Value && is_type_typeid(type)) {
+6
View File
@@ -77,6 +77,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,
@@ -326,6 +329,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},
+1 -1
View File
@@ -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,
+13 -13
View File
@@ -2806,17 +2806,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)) {
// gb_printf_err("%s %s\n", token_pos_to_string(expr_pos), expr_to_string(expr));
// if (is_type_untyped(type)) {
// 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
return lb_const_value(p->module, tv.type, tv.value);
return lb_const_value(p->module, type, tv.value);
}
#if 0
@@ -2847,12 +2848,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;
@@ -2893,7 +2894,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);
@@ -2966,7 +2967,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)) {
@@ -2986,16 +2986,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);
@@ -3005,7 +3005,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;
+88 -50
View File
@@ -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);
@@ -1487,61 +1546,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 {};
}
@@ -1647,6 +1666,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:
+6 -3
View File
@@ -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<String> 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<String> args) {
build_context.show_error_line = true;
break;
case BuildFlag_IgnoreLazy:
case BuildFlag_InternalIgnoreLazy:
build_context.ignore_lazy = true;
break;
+22 -18
View File
@@ -114,16 +114,17 @@ gb_internal isize map__add_entry(Map<T> *h, HashKey const &key) {
template <typename T>
gb_internal MapFindResult map__find(Map<T> *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<T> *h, HashKey const &key) {
template <typename T>
gb_internal MapFindResult map__find_from_entry(Map<T> *h, MapEntry<T> *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<T> *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;
+4 -2
View File
@@ -2572,6 +2572,9 @@ bool is_literal_type(Ast *node) {
case Ast_MatrixType:
case Ast_CallExpr:
return true;
case Ast_MultiPointerType:
// For better error messages
return true;
}
return false;
}
@@ -5426,8 +5429,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;
+1 -1
View File
@@ -28,9 +28,9 @@ enum AddressingMode : u8 {
};
struct TypeAndValue {
Type * type;
AddressingMode mode;
bool is_lhs; // Debug info
Type * type;
ExactValue value;
};
+5 -5
View File
@@ -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() ---
+3 -3
View File
@@ -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',