From d556fa2cd8570363a66a7d8a2a5abf5ba306e954 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 3 Jun 2018 15:06:40 +0100 Subject: [PATCH] Remove special shared scope for runtime stuff --- core/fmt/fmt.odin | 128 ++++++++++++------------- core/mem/alloc.odin | 59 +++++------- core/mem/mem.odin | 26 +++--- core/mem/raw.odin | 51 ++++++++++ core/os/os.odin | 39 +++++++- core/raw/raw.odin | 51 ---------- core/runtime/core.odin | 153 ++++++++++++++---------------- core/runtime/internal.odin | 20 ++-- core/runtime/soft_numbers.odin | 112 ---------------------- core/sort/sort.odin | 4 +- core/strings/strings.odin | 4 +- core/thread/thread_windows.odin | 3 +- core/types/types.odin | 158 +++++++++++++++---------------- examples/demo/demo.odin | 8 +- src/check_expr.cpp | 5 +- src/checker.cpp | 161 +++++++++++++++++++++----------- src/checker.hpp | 42 +++++---- src/common.cpp | 6 +- src/ir.cpp | 102 ++++++++++---------- src/parser.cpp | 3 +- 20 files changed, 544 insertions(+), 591 deletions(-) create mode 100644 core/mem/raw.odin delete mode 100644 core/raw/raw.odin delete mode 100644 core/runtime/soft_numbers.odin diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 497d23520..aef743ee9 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -1,11 +1,11 @@ package fmt +import "core:runtime" import "core:os" import "core:mem" import "core:unicode/utf8" import "core:types" import "core:strconv" -import "core:raw" _BUFFER_SIZE :: 1<<12; @@ -33,8 +33,8 @@ Fmt_Info :: struct { } string_buffer_from_slice :: proc(backing: []byte) -> String_Buffer { - s := transmute(raw.Slice)backing; - d := raw.Dynamic_Array{ + s := transmute(mem.Raw_Slice)backing; + d := mem.Raw_Dynamic_Array{ data = s.data, len = 0, cap = s.len, @@ -145,7 +145,7 @@ bprintf :: proc(buf: []byte, fmt: string, args: ...any) -> string { -fprint_type :: proc(fd: os.Handle, info: ^Type_Info) { +fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) { data: [_BUFFER_SIZE]byte; buf := string_buffer_from_slice(data[..]); write_type(&buf, info); @@ -156,18 +156,18 @@ write_typeid :: proc(buf: ^String_Buffer, id: typeid) { write_type(buf, type_info_of(id)); } -write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { +write_type :: proc(buf: ^String_Buffer, ti: ^runtime.Type_Info) { if ti == nil { write_string(buf, "nil"); return; } switch info in ti.variant { - case Type_Info_Named: + case runtime.Type_Info_Named: write_string(buf, info.name); - case Type_Info_Integer: + case runtime.Type_Info_Integer: a := any{typeid = typeid_of(ti)}; - switch _ in a { + switch in a { case int: write_string(buf, "int"); case uint: write_string(buf, "uint"); case uintptr: write_string(buf, "uintptr"); @@ -175,47 +175,47 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { write_byte(buf, info.signed ? 'i' : 'u'); write_i64(buf, i64(8*ti.size), 10); } - case Type_Info_Rune: + case runtime.Type_Info_Rune: write_string(buf, "rune"); - case Type_Info_Float: + case runtime.Type_Info_Float: write_byte(buf, 'f'); write_i64(buf, i64(8*ti.size), 10); - case Type_Info_Complex: + case runtime.Type_Info_Complex: write_string(buf, "complex"); write_i64(buf, i64(8*ti.size), 10); - case Type_Info_String: + case runtime.Type_Info_String: if info.is_cstring { write_string(buf, "cstring"); } else { write_string(buf, "string"); } - case Type_Info_Boolean: + case runtime.Type_Info_Boolean: a := any{typeid = typeid_of(ti)}; - switch _ in a { + switch in a { case bool: write_string(buf, "bool"); case: write_byte(buf, 'b'); write_i64(buf, i64(8*ti.size), 10); } - case Type_Info_Any: + case runtime.Type_Info_Any: write_string(buf, "any"); - case Type_Info_Type_Id: + case runtime.Type_Info_Type_Id: write_string(buf, "typeid"); - case Type_Info_Pointer: + case runtime.Type_Info_Pointer: if info.elem == nil { write_string(buf, "rawptr"); } else { write_string(buf, "^"); write_type(buf, info.elem); } - case Type_Info_Procedure: + case runtime.Type_Info_Procedure: write_string(buf, "proc"); if info.params == nil { write_string(buf, "()"); } else { - t := info.params.variant.(Type_Info_Tuple); + t := info.params.variant.(runtime.Type_Info_Tuple); write_string(buf, "("); for t, i in t.types { if i > 0 do write_string(buf, ", "); @@ -227,7 +227,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { write_string(buf, " -> "); write_type(buf, info.results); } - case Type_Info_Tuple: + case runtime.Type_Info_Tuple: count := len(info.names); if count != 1 do write_string(buf, "("); for name, i in info.names { @@ -243,25 +243,25 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { } if count != 1 do write_string(buf, ")"); - case Type_Info_Array: + case runtime.Type_Info_Array: write_string(buf, "["); write_i64(buf, i64(info.count), 10); write_string(buf, "]"); write_type(buf, info.elem); - case Type_Info_Dynamic_Array: + case runtime.Type_Info_Dynamic_Array: write_string(buf, "[dynamic]"); write_type(buf, info.elem); - case Type_Info_Slice: + case runtime.Type_Info_Slice: write_string(buf, "[]"); write_type(buf, info.elem); - case Type_Info_Map: + case runtime.Type_Info_Map: write_string(buf, "map["); write_type(buf, info.key); write_byte(buf, ']'); write_type(buf, info.value); - case Type_Info_Struct: + case runtime.Type_Info_Struct: write_string(buf, "struct "); if info.is_packed do write_string(buf, "#packed "); if info.is_raw_union do write_string(buf, "#raw_union "); @@ -279,7 +279,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { } write_byte(buf, '}'); - case Type_Info_Union: + case runtime.Type_Info_Union: write_string(buf, "union {"); for variant, i in info.variants { if i > 0 do write_string(buf, ", "); @@ -287,7 +287,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { } write_string(buf, "}"); - case Type_Info_Enum: + case runtime.Type_Info_Enum: write_string(buf, "enum "); write_type(buf, info.base); if info.is_export do write_string(buf, " #export"); @@ -298,7 +298,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { } write_string(buf, "}"); - case Type_Info_Bit_Field: + case runtime.Type_Info_Bit_Field: write_string(buf, "bit_field "); if ti.align != 1 { write_string(buf, "#align "); @@ -371,7 +371,7 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) { ok := true; if arg_index < len(args) { arg := args[arg_index]; - arg.typeid = typeid_base(arg.typeid); + arg.typeid = runtime.typeid_base(arg.typeid); switch i in arg { case int: num = i; case i8: num = int(i); @@ -630,13 +630,13 @@ fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) { } enum_value_to_string :: proc(v: any) -> (string, bool) { - v.typeid = typeid_base(v.typeid); + v.typeid = runtime.typeid_base(v.typeid); type_info := type_info_of(v.typeid); switch e in type_info.variant { case: return "", false; - case Type_Info_Enum: - get_str :: proc(i: $T, e: Type_Info_Enum) -> (string, bool) { + case runtime.Type_Info_Enum: + get_str :: proc(i: $T, e: runtime.Type_Info_Enum) -> (string, bool) { if types.is_string(e.base) { for val, idx in e.values { if v, ok := val.(T); ok && v == i { @@ -655,7 +655,7 @@ enum_value_to_string :: proc(v: any) -> (string, bool) { return "", false; } - a := any{v.data, typeid_of(type_info_base(e.base))}; + a := any{v.data, typeid_of(runtime.type_info_base(e.base))}; switch v in a { case rune: return get_str(v, e); case i8: return get_str(v, e); @@ -701,11 +701,11 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) { type_info := type_info_of(v.typeid); switch e in type_info.variant { case: fmt_bad_verb(fi, verb); - case Type_Info_Enum: + case runtime.Type_Info_Enum: switch verb { case: fmt_bad_verb(fi, verb); case 'd', 'f': - fmt_arg(fi, any{v.data, typeid_of(type_info_base(e.base))}, verb); + fmt_arg(fi, any{v.data, typeid_of(runtime.type_info_base(e.base))}, verb); case 's', 'v': str, ok := enum_value_to_string(v); if !ok do str = "!%(BAD ENUM VALUE)"; @@ -723,9 +723,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { type_info := type_info_of(v.typeid); switch info in type_info.variant { - case Type_Info_Named: + case runtime.Type_Info_Named: switch b in info.base.variant { - case Type_Info_Struct: + case runtime.Type_Info_Struct: if verb != 'v' { fmt_bad_verb(fi, verb); return; @@ -770,21 +770,21 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { fmt_value(fi, any{v.data, typeid_of(info.base)}, verb); } - case Type_Info_Boolean: fmt_arg(fi, v, verb); - case Type_Info_Integer: fmt_arg(fi, v, verb); - case Type_Info_Rune: fmt_arg(fi, v, verb); - case Type_Info_Float: fmt_arg(fi, v, verb); - case Type_Info_Complex: fmt_arg(fi, v, verb); - case Type_Info_String: fmt_arg(fi, v, verb); + case runtime.Type_Info_Boolean: fmt_arg(fi, v, verb); + case runtime.Type_Info_Integer: fmt_arg(fi, v, verb); + case runtime.Type_Info_Rune: fmt_arg(fi, v, verb); + case runtime.Type_Info_Float: fmt_arg(fi, v, verb); + case runtime.Type_Info_Complex: fmt_arg(fi, v, verb); + case runtime.Type_Info_String: fmt_arg(fi, v, verb); - case Type_Info_Pointer: - if v.typeid == typeid_of(^Type_Info) { - write_type(fi.buf, (^^Type_Info)(v.data)^); + case runtime.Type_Info_Pointer: + if v.typeid == typeid_of(^runtime.Type_Info) { + write_type(fi.buf, (^^runtime.Type_Info)(v.data)^); } else { fmt_pointer(fi, (^rawptr)(v.data)^, verb); } - case Type_Info_Array: + case runtime.Type_Info_Array: write_byte(fi.buf, '['); defer write_byte(fi.buf, ']'); for i in 0..info.count { @@ -794,10 +794,10 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { fmt_arg(fi, any{rawptr(data), typeid_of(info.elem)}, verb); } - case Type_Info_Dynamic_Array: + case runtime.Type_Info_Dynamic_Array: write_byte(fi.buf, '['); defer write_byte(fi.buf, ']'); - array := cast(^raw.Dynamic_Array)v.data; + array := cast(^mem.Raw_Dynamic_Array)v.data; for i in 0..array.len { if i > 0 do write_string(fi.buf, ", "); @@ -805,10 +805,10 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { fmt_arg(fi, any{rawptr(data), typeid_of(info.elem)}, verb); } - case Type_Info_Slice: + case runtime.Type_Info_Slice: write_byte(fi.buf, '['); defer write_byte(fi.buf, ']'); - slice := cast(^raw.Slice)v.data; + slice := cast(^mem.Raw_Slice)v.data; for i in 0..slice.len { if i > 0 do write_string(fi.buf, ", "); @@ -816,7 +816,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { fmt_arg(fi, any{rawptr(data), typeid_of(info.elem)}, verb); } - case Type_Info_Map: + case runtime.Type_Info_Map: if verb != 'v' { fmt_bad_verb(fi, verb); return; @@ -825,20 +825,20 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { write_string(fi.buf, "map["); defer write_byte(fi.buf, ']'); - m := (^raw.Map)(v.data); + m := (^mem.Raw_Map)(v.data); if m != nil { assert(info.generated_struct != nil); entries := &m.entries; - gs := type_info_base(info.generated_struct).variant.(Type_Info_Struct); - ed := type_info_base(gs.types[1]).variant.(Type_Info_Dynamic_Array); - entry_type := ed.elem.variant.(Type_Info_Struct); + gs := runtime.type_info_base(info.generated_struct).variant.(runtime.Type_Info_Struct); + ed := runtime.type_info_base(gs.types[1]).variant.(runtime.Type_Info_Dynamic_Array); + entry_type := ed.elem.variant.(runtime.Type_Info_Struct); entry_size := ed.elem_size; for i in 0..entries.len { if i > 0 do write_string(fi.buf, ", "); data := uintptr(entries.data) + uintptr(i*entry_size); - header := cast(^__Map_Entry_Header)data; + header := cast(^runtime.Map_Entry_Header)data; if types.is_string(info.key) { write_string(fi.buf, header.key.str); @@ -854,7 +854,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { } } - case Type_Info_Struct: + case runtime.Type_Info_Struct: if info.is_raw_union { write_string(fi.buf, "(raw_union)"); return; @@ -890,7 +890,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { if hash do write_string(fi.buf, ",\n"); } - case Type_Info_Union: + case runtime.Type_Info_Union: tag_ptr := uintptr(v.data) + info.tag_offset; tag_any := any{rawptr(tag_ptr), typeid_of(info.tag_type)}; @@ -914,10 +914,10 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { fmt_arg(fi, any{v.data, id}, verb); } - case Type_Info_Enum: + case runtime.Type_Info_Enum: fmt_enum(fi, v, verb); - case Type_Info_Procedure: + case runtime.Type_Info_Procedure: ptr := (^rawptr)(v.data)^; if ptr == nil { write_string(fi.buf, "nil"); @@ -927,7 +927,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { fmt_pointer(fi, ptr, 'p'); } - case Type_Info_Type_Id: + case runtime.Type_Info_Type_Id: id := (^typeid)(v.data)^; write_typeid(fi.buf, id); } @@ -960,14 +960,14 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) { if verb == 'T' { ti := type_info_of(arg.typeid); switch a in arg { - case ^Type_Info: ti = a; + case ^runtime.Type_Info: ti = a; } write_type(fi.buf, ti); return; } base_arg := arg; - base_arg.typeid = typeid_base(base_arg.typeid); + base_arg.typeid = runtime.typeid_base(base_arg.typeid); switch a in base_arg { case bool: fmt_bool(fi, bool(a), verb); case b8: fmt_bool(fi, bool(a), verb); diff --git a/core/mem/alloc.odin b/core/mem/alloc.odin index 51e4faac2..6c9664917 100644 --- a/core/mem/alloc.odin +++ b/core/mem/alloc.odin @@ -1,7 +1,24 @@ package mem -import "core:raw" -import "core:os" +DEFAULT_ALIGNMENT :: 2*align_of(rawptr); + +Allocator_Mode :: enum byte { + Alloc, + Free, + Free_All, + Resize, +} + +Allocator_Proc :: #type proc(allocator_data: rawptr, mode: Allocator_Mode, + size, alignment: int, + old_memory: rawptr, old_size: int, flags: u64 = 0, location := #caller_location) -> rawptr; + + +Allocator :: struct { + procedure: Allocator_Proc, + data: rawptr, +} + alloc :: inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> rawptr { @@ -30,16 +47,16 @@ resize :: inline proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEF free_string :: proc(str: string, loc := #caller_location) { - free_ptr(raw.data(str), loc); + free_ptr(raw_data(str), loc); } free_cstring :: proc(str: cstring, loc := #caller_location) { free_ptr((^byte)(str), loc); } free_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) { - free_ptr(raw.data(array), loc); + free_ptr(raw_data(array), loc); } free_slice :: proc(array: $T/[]$E, loc := #caller_location) { - free_ptr(raw.data(array), loc); + free_ptr(raw_data(array), loc); } free_map :: proc(m: $T/map[$K]$V, loc := #caller_location) { raw := transmute(raw.Map)m; @@ -78,38 +95,6 @@ default_resize_align :: proc(old_memory: rawptr, old_size, new_size, alignment: } -default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, - size, alignment: int, - old_memory: rawptr, old_size: int, flags: u64 = 0, loc := #caller_location) -> rawptr { - using Allocator_Mode; - - switch mode { - case Alloc: - return os.heap_alloc(size); - - case Free: - os.heap_free(old_memory); - return nil; - - case Free_All: - // NOTE(bill): Does nothing - - case Resize: - ptr := os.heap_resize(old_memory, size); - assert(ptr != nil); - return ptr; - } - - return nil; -} - -default_allocator :: proc() -> Allocator { - return Allocator{ - procedure = default_allocator_proc, - data = nil, - }; -} - nil_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, flags: u64 = 0, loc := #caller_location) -> rawptr { diff --git a/core/mem/mem.odin b/core/mem/mem.odin index 18cd970d4..9c083c009 100644 --- a/core/mem/mem.odin +++ b/core/mem/mem.odin @@ -1,6 +1,6 @@ package mem -import "core:raw" +import "core:runtime" foreign _ { @(link_name = "llvm.bswap.i16") swap16 :: proc(b: u16) -> u16 ---; @@ -80,20 +80,20 @@ ptr_sub :: proc "contextless" (a, b: $P/^$T) -> int { slice_ptr :: proc "contextless" (ptr: ^$T, len: int) -> []T { assert(len >= 0); - slice := raw.Slice{data = ptr, len = len}; + slice := Raw_Slice{data = ptr, len = len}; return transmute([]T)slice; } slice_to_bytes :: proc "contextless" (slice: $E/[]$T) -> []byte { - s := transmute(raw.Slice)slice; + s := transmute(Raw_Slice)slice; s.len *= size_of(T); return transmute([]byte)s; } buffer_from_slice :: proc(backing: $T/[]$E) -> [dynamic]E { - s := transmute(raw.Slice)backing; - d := raw.Dynamic_Array{ + s := transmute(Raw_Slice)backing; + d := Raw_Dynamic_Array{ data = s.data, len = 0, cap = s.len, @@ -104,13 +104,13 @@ buffer_from_slice :: proc(backing: $T/[]$E) -> [dynamic]E { ptr_to_bytes :: proc "contextless" (ptr: ^$T, len := 1) -> []byte { assert(len >= 0); - return transmute([]byte)raw.Slice{ptr, len*size_of(T)}; + return transmute([]byte)Raw_Slice{ptr, len*size_of(T)}; } any_to_bytes :: proc "contextless" (val: any) -> []byte { ti := type_info_of(val.typeid); size := ti != nil ? ti.size : 0; - return transmute([]byte)raw.Slice{val.data, size}; + return transmute([]byte)Raw_Slice{val.data, size}; } @@ -158,8 +158,8 @@ allocation_header :: proc(data: rawptr) -> ^AllocationHeader { Fixed_Byte_Buffer :: distinct [dynamic]byte; make_fixed_byte_buffer :: proc(backing: []byte) -> Fixed_Byte_Buffer { - s := transmute(raw.Slice)backing; - d: raw.Dynamic_Array; + s := transmute(Raw_Slice)backing; + d: Raw_Dynamic_Array; d.data = s.data; d.len = 0; d.cap = s.len; @@ -199,7 +199,7 @@ init_arena_from_context :: proc(using a: ^Arena, size: int) { } -context_from_allocator :: proc(a: Allocator) -> Context { +context_from_allocator :: proc(a: Allocator) -> runtime.Context { c := context; c.allocator = a; return c; @@ -241,7 +241,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, #no_bounds_check end := &arena.memory[len(arena.memory)]; ptr := align_forward(end, uintptr(alignment)); - (^raw.Slice)(&arena.memory).len += total_size; + (^Raw_Slice)(&arena.memory).len += total_size; return zero(ptr, size); case Free: @@ -249,7 +249,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, // Use ArenaTempMemory if you want to free a block case Free_All: - (^raw.Slice)(&arena.memory).len = 0; + (^Raw_Slice)(&arena.memory).len = 0; case Resize: return default_resize_align(old_memory, old_size, size, alignment); @@ -269,7 +269,7 @@ begin_arena_temp_memory :: proc(a: ^Arena) -> ArenaTempMemory { end_arena_temp_memory :: proc(using tmp: ArenaTempMemory) { assert(len(arena.memory) >= original_count); assert(arena.temp_count > 0); - (^raw.Dynamic_Array)(&arena.memory).len = original_count; + (^Raw_Dynamic_Array)(&arena.memory).len = original_count; arena.temp_count -= 1; } diff --git a/core/mem/raw.odin b/core/mem/raw.odin new file mode 100644 index 000000000..11c2a9404 --- /dev/null +++ b/core/mem/raw.odin @@ -0,0 +1,51 @@ +package mem + +Raw_Any :: struct { + data: rawptr, + typeid: typeid, +} + +Raw_String :: struct { + data: ^byte, + len: int, +} + +Raw_Cstring :: struct { + data: ^byte, +} + +Raw_Slice :: struct { + data: rawptr, + len: int, +} + +Raw_Dynamic_Array :: struct { + data: rawptr, + len: int, + cap: int, + allocator: Allocator, +} + +Raw_Map :: struct { + hashes: [dynamic]int, + entries: Raw_Dynamic_Array, +} + + +make_any :: inline proc(data: rawptr, id: typeid) -> any { + return transmute(any)Raw_Any{data, id}; +} + +raw_string_data :: inline proc(s: $T/string) -> ^byte { + return (^Raw_String)(&s).data; +} +raw_slice_data :: inline proc(a: $T/[]$E) -> ^E { + return cast(^E)(^Raw_Slice)(&a).data; +} +raw_dynamic_array_data :: inline proc(a: $T/[dynamic]$E) -> ^E { + return cast(^E)(^Raw_Dynamic_Array)(&a).data; +} + +raw_data :: proc[raw_string_data, raw_slice_data, raw_dynamic_array_data]; + + diff --git a/core/os/os.odin b/core/os/os.odin index f38cad55a..c7a4dc733 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -1,6 +1,6 @@ package os -import "core:raw" +import "core:mem" write_string :: proc(fd: Handle, str: string) -> (int, Errno) { return write(fd, cast([]byte)str); @@ -56,11 +56,44 @@ write_entire_file :: proc(name: string, data: []byte, truncate := true) -> (succ } write_ptr :: proc(fd: Handle, data: rawptr, len: int) -> (int, Errno) { - s := transmute([]byte)raw.Slice{data, len}; + s := transmute([]byte)mem.Raw_Slice{data, len}; return write(fd, s); } read_ptr :: proc(fd: Handle, data: rawptr, len: int) -> (int, Errno) { - s := transmute([]byte)raw.Slice{data, len}; + s := transmute([]byte)mem.Raw_Slice{data, len}; return read(fd, s); } + + +default_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode, + size, alignment: int, + old_memory: rawptr, old_size: int, flags: u64 = 0, loc := #caller_location) -> rawptr { + using mem.Allocator_Mode; + + switch mode { + case Alloc: + return heap_alloc(size); + + case Free: + heap_free(old_memory); + return nil; + + case Free_All: + // NOTE(bill): Does nothing + + case Resize: + ptr := heap_resize(old_memory, size); + assert(ptr != nil); + return ptr; + } + + return nil; +} + +default_allocator :: proc() -> mem.Allocator { + return mem.Allocator{ + procedure = default_allocator_proc, + data = nil, + }; +} diff --git a/core/raw/raw.odin b/core/raw/raw.odin deleted file mode 100644 index 94019f95b..000000000 --- a/core/raw/raw.odin +++ /dev/null @@ -1,51 +0,0 @@ -package raw - -Any :: struct { - data: rawptr, - typeid: typeid, -} - -String :: struct { - data: ^byte, - len: int, -} - -Cstring :: struct { - data: ^byte, -} - -Slice :: struct { - data: rawptr, - len: int, -} - -Dynamic_Array :: struct { - data: rawptr, - len: int, - cap: int, - allocator: Allocator, -} - -Map :: struct { - hashes: [dynamic]int, - entries: Dynamic_Array, -} - - -make_any :: inline proc(data: rawptr, id: typeid) -> any { - return transmute(any)Any{data, id}; -} - -string_data :: inline proc(s: $T/string) -> ^byte { - return (^String)(&s).data; -} -slice_data :: inline proc(a: $T/[]$E) -> ^E { - return cast(^E)(^Slice)(&a).data; -} -dynamic_array_data :: inline proc(a: $T/[dynamic]$E) -> ^E { - return cast(^E)(^Dynamic_Array)(&a).data; -} - -data :: proc[string_data, slice_data, dynamic_array_data]; - - diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 57835acb6..da5bdaef9 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -4,7 +4,6 @@ package runtime import "core:os" -import "core:raw" import "core:mem" // Naming Conventions: @@ -134,9 +133,9 @@ Type_Info :: struct { // NOTE(bill): only the ones that are needed (not all types) // This will be set by the compiler -__type_table: []Type_Info; +type_table: []Type_Info; -__args__: []cstring; +args__: []cstring; // IMPORTANT NOTE(bill): Must be in this order (as the compiler relies upon it) @@ -147,27 +146,8 @@ Source_Code_Location :: struct { procedure: string, } -Allocator_Mode :: enum byte { - Alloc, - Free, - Free_All, - Resize, -} - -Allocator_Proc :: #type proc(allocator_data: rawptr, mode: Allocator_Mode, - size, alignment: int, - old_memory: rawptr, old_size: int, flags: u64 = 0, location := #caller_location) -> rawptr; - - -Allocator :: struct { - procedure: Allocator_Proc, - data: rawptr, -} - - - Context :: struct { - allocator: Allocator, + allocator: mem.Allocator, thread_id: int, user_data: any, @@ -177,34 +157,33 @@ Context :: struct { derived: any, // May be used for derived data types } -DEFAULT_ALIGNMENT :: 2*align_of(rawptr); -__INITIAL_MAP_CAP :: 16; +INITIAL_MAP_CAP :: 16; -__Map_Key :: struct { +Map_Key :: struct { hash: u64, str: string, } -__Map_Find_Result :: struct { +Map_Find_Result :: struct { hash_index: int, entry_prev: int, entry_index: int, } -__Map_Entry_Header :: struct { - key: __Map_Key, +Map_Entry_Header :: struct { + key: Map_Key, next: int, /* value: Value_Type, */ } -__Map_Header :: struct { - m: ^raw.Map, +Map_Header :: struct { + m: ^mem.Raw_Map, is_key_string: bool, entry_size: int, entry_align: int, @@ -251,10 +230,10 @@ __typeid_of :: proc "contextless" (ti: ^Type_Info) -> typeid { } __type_info_of :: proc "contextless" (id: typeid) -> ^Type_Info { n := int(transmute(uintptr)id); - if n < 0 || n >= len(__type_table) { + if n < 0 || n >= len(type_table) { n = 0; } - return &__type_table[n]; + return &type_table[n]; } typeid_base :: proc "contextless" (id: typeid) -> typeid { @@ -297,17 +276,13 @@ __init_context_from_ptr :: proc "contextless" (c: ^Context, other: ^Context) { __init_context :: proc "contextless" (c: ^Context) { if c == nil do return; - if c.allocator.procedure == nil { - c.allocator = mem.default_allocator(); - } - if c.thread_id == 0 { - c.thread_id = os.current_thread_id(); - } + c.allocator = os.default_allocator(); + c.thread_id = os.current_thread_id(); } - +@(builtin) copy :: proc "contextless" (dst, src: $T/[]$E) -> int { n := max(0, min(len(dst), len(src))); if n > 0 do mem.copy(&dst[0], &src[0], n*size_of(E)); @@ -316,33 +291,38 @@ copy :: proc "contextless" (dst, src: $T/[]$E) -> int { +@(builtin) pop :: proc "contextless" (array: ^$T/[dynamic]$E) -> E { if array == nil do return E{}; assert(len(array) > 0); res := array[len(array)-1]; - (^raw.Dynamic_Array)(array).len -= 1; + (^mem.Raw_Dynamic_Array)(array).len -= 1; return res; } - +@(builtin) clear :: proc[clear_dynamic_array, clear_map]; + +@(builtin) reserve :: proc[reserve_dynamic_array, reserve_map]; - +@(builtin) new :: inline proc(T: type, loc := #caller_location) -> ^T { ptr := (^T)(mem.alloc(size_of(T), align_of(T), loc)); ptr^ = T{}; return ptr; } + +@(builtin) new_clone :: inline proc(data: $T, loc := #caller_location) -> ^T { ptr := (^T)(mem.alloc(size_of(T), align_of(T), loc)); ptr^ = data; return ptr; } - +@(builtin) free :: proc[ mem.free_ptr, mem.free_string, @@ -355,25 +335,29 @@ free :: proc[ +@(builtin) clear_map :: inline proc "contextless" (m: ^$T/map[$K]$V) { if m == nil do return; - raw_map := (^raw.Map)(m); - hashes := (^raw.Dynamic_Array)(&raw_map.hashes); - entries := (^raw.Dynamic_Array)(&raw_map.entries); + raw_map := (^mem.Raw_Map)(m); + hashes := (^mem.Raw_Dynamic_Array)(&raw_map.hashes); + entries := (^mem.Raw_Dynamic_Array)(&raw_map.entries); hashes.len = 0; entries.len = 0; } +@(builtin) reserve_map :: proc(m: ^$T/map[$K]$V, capacity: int) { if m != nil do __dynamic_map_reserve(__get_map_header(m), capacity); } +@(builtin) delete :: proc(m: ^$T/map[$K]$V, key: K) { if m != nil do __dynamic_map_delete(__get_map_header(m), __get_map_key(key)); } +@(builtin) append :: proc(array: ^$T/[dynamic]$E, args: ...E, loc := #caller_location) -> int { if array == nil do return 0; @@ -387,7 +371,7 @@ append :: proc(array: ^$T/[dynamic]$E, args: ...E, loc := #caller_location) -> i } arg_len = min(cap(array)-len(array), arg_len); if arg_len > 0 { - a := (^raw.Dynamic_Array)(array); + a := (^mem.Raw_Dynamic_Array)(array); data := (^E)(a.data); assert(data != nil); mem.copy(mem.ptr_offset(data, uintptr(a.len)), &args[0], size_of(E) * arg_len); @@ -396,6 +380,7 @@ append :: proc(array: ^$T/[dynamic]$E, args: ...E, loc := #caller_location) -> i return len(array); } +@(builtin) append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ...string, loc := #caller_location) -> int { for arg in args { append(array = array, args = ([]E)(arg), loc = loc); @@ -403,13 +388,15 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ...string, loc := #caller return len(array); } +@(builtin) clear_dynamic_array :: inline proc "contextless" (array: ^$T/[dynamic]$E) { - if array != nil do (^raw.Dynamic_Array)(array).len = 0; + if array != nil do (^mem.Raw_Dynamic_Array)(array).len = 0; } +@(builtin) reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> bool { if array == nil do return false; - a := (^raw.Dynamic_Array)(array); + a := (^mem.Raw_Dynamic_Array)(array); if capacity <= a.cap do return true; @@ -423,7 +410,7 @@ reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #cal allocator := a.allocator; new_data := allocator.procedure( - allocator.data, Allocator_Mode.Resize, new_size, align_of(E), + allocator.data, mem.Allocator_Mode.Resize, new_size, align_of(E), a.data, old_size, 0, loc, ); if new_data == nil do return false; @@ -438,6 +425,7 @@ reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #cal +@(builtin) assert :: proc "contextless" (condition: bool, message := "", using loc := #caller_location) -> bool { if !condition { fd := os.stderr; @@ -453,6 +441,7 @@ assert :: proc "contextless" (condition: bool, message := "", using loc := #call return condition; } +@(builtin) panic :: proc "contextless" (message := "", using loc := #caller_location) { fd := os.stderr; __print_caller_location(fd, loc); @@ -471,7 +460,7 @@ panic :: proc "contextless" (message := "", using loc := #caller_location) { __dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, cap: int, loc := #caller_location) { - array := (^raw.Dynamic_Array)(array_); + array := (^mem.Raw_Dynamic_Array)(array_); array.allocator = context.allocator; assert(array.allocator.procedure != nil); @@ -482,7 +471,7 @@ __dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, ca } __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: int, loc := #caller_location) -> bool { - array := (^raw.Dynamic_Array)(array_); + array := (^mem.Raw_Dynamic_Array)(array_); if cap <= array.cap do return true; @@ -495,7 +484,7 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: new_size := cap * elem_size; allocator := array.allocator; - new_data := allocator.procedure(allocator.data, Allocator_Mode.Resize, new_size, elem_align, array.data, old_size, 0, loc); + new_data := allocator.procedure(allocator.data, mem.Allocator_Mode.Resize, new_size, elem_align, array.data, old_size, 0, loc); if new_data == nil do return false; array.data = new_data; @@ -504,7 +493,7 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: } __dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len: int, loc := #caller_location) -> bool { - array := (^raw.Dynamic_Array)(array_); + array := (^mem.Raw_Dynamic_Array)(array_); ok := __dynamic_array_reserve(array_, elem_size, elem_align, len, loc); if ok do array.len = len; @@ -514,7 +503,7 @@ __dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len: __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int, items: rawptr, item_count: int, loc := #caller_location) -> int { - array := (^raw.Dynamic_Array)(array_); + array := (^mem.Raw_Dynamic_Array)(array_); if items == nil do return 0; if item_count <= 0 do return 0; @@ -537,7 +526,7 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int, } __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: int, loc := #caller_location) -> int { - array := (^raw.Dynamic_Array)(array_); + array := (^mem.Raw_Dynamic_Array)(array_); ok := true; if array.cap <= array.len+1 { @@ -559,10 +548,10 @@ __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: in // Map -__get_map_header :: proc "contextless" (m: ^$T/map[$K]$V) -> __Map_Header { - header := __Map_Header{m = (^raw.Map)(m)}; +__get_map_header :: proc "contextless" (m: ^$T/map[$K]$V) -> Map_Header { + header := Map_Header{m = (^mem.Raw_Map)(m)}; Entry :: struct { - key: __Map_Key, + key: Map_Key, next: int, value: V, } @@ -576,8 +565,8 @@ __get_map_header :: proc "contextless" (m: ^$T/map[$K]$V) -> __Map_Header { return header; } -__get_map_key :: proc "contextless" (key: $K) -> __Map_Key { - map_key: __Map_Key; +__get_map_key :: proc "contextless" (key: $K) -> Map_Key { + map_key: Map_Key; ti := type_info_base_without_enum(type_info_of(K)); switch _ in ti.variant { case Type_Info_Integer: @@ -621,17 +610,17 @@ __default_hash :: proc(data: []byte) -> u64 { } __default_hash_string :: proc(s: string) -> u64 do return __default_hash(([]byte)(s)); -__dynamic_map_reserve :: proc(using header: __Map_Header, cap: int, loc := #caller_location) { +__dynamic_map_reserve :: proc(using header: Map_Header, cap: int, loc := #caller_location) { __dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap, loc); __dynamic_array_reserve(&m.entries, entry_size, entry_align, cap, loc); } -__dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc := #caller_location) #no_bounds_check { - new_header: __Map_Header = header; - nm: raw.Map; +__dynamic_map_rehash :: proc(using header: Map_Header, new_count: int, loc := #caller_location) #no_bounds_check { + new_header: Map_Header = header; + nm: mem.Raw_Map; new_header.m = &nm; - header_hashes := (^raw.Dynamic_Array)(&header.m.hashes); - nm_hashes := (^raw.Dynamic_Array)(&nm.hashes); + header_hashes := (^mem.Raw_Dynamic_Array)(&header.m.hashes); + nm_hashes := (^mem.Raw_Dynamic_Array)(&nm.hashes); __dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count, loc); __dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len, loc); @@ -664,7 +653,7 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc := header.m^ = nm; } -__dynamic_map_get :: proc(h: __Map_Header, key: __Map_Key) -> rawptr { +__dynamic_map_get :: proc(h: Map_Header, key: Map_Key) -> rawptr { index := __dynamic_map_find(h, key).entry_index; if index >= 0 { data := uintptr(__dynamic_map_get_entry(h, index)); @@ -673,13 +662,13 @@ __dynamic_map_get :: proc(h: __Map_Header, key: __Map_Key) -> rawptr { return nil; } -__dynamic_map_set :: proc(h: __Map_Header, key: __Map_Key, value: rawptr, loc := #caller_location) #no_bounds_check { +__dynamic_map_set :: proc(h: Map_Header, key: Map_Key, value: rawptr, loc := #caller_location) #no_bounds_check { index: int; assert(value != nil); if len(h.m.hashes) == 0 { - __dynamic_map_reserve(h, __INITIAL_MAP_CAP, loc); + __dynamic_map_reserve(h, INITIAL_MAP_CAP, loc); __dynamic_map_grow(h, loc); } @@ -708,18 +697,18 @@ __dynamic_map_set :: proc(h: __Map_Header, key: __Map_Key, value: rawptr, loc := } -__dynamic_map_grow :: proc(using h: __Map_Header, loc := #caller_location) { +__dynamic_map_grow :: proc(using h: Map_Header, loc := #caller_location) { // TODO(bill): Determine an efficient growing rate - new_count := max(4*m.entries.cap + 7, __INITIAL_MAP_CAP); + new_count := max(4*m.entries.cap + 7, INITIAL_MAP_CAP); __dynamic_map_rehash(h, new_count, loc); } -__dynamic_map_full :: inline proc(using h: __Map_Header) -> bool { +__dynamic_map_full :: inline proc(using h: Map_Header) -> bool { return int(0.75 * f64(len(m.hashes))) <= m.entries.cap; } -__dynamic_map_hash_equal :: proc(h: __Map_Header, a, b: __Map_Key) -> bool { +__dynamic_map_hash_equal :: proc(h: Map_Header, a, b: Map_Key) -> bool { if a.hash == b.hash { if h.is_key_string do return a.str == b.str; return true; @@ -727,8 +716,8 @@ __dynamic_map_hash_equal :: proc(h: __Map_Header, a, b: __Map_Key) -> bool { return false; } -__dynamic_map_find :: proc(using h: __Map_Header, key: __Map_Key) -> __Map_Find_Result #no_bounds_check { - fr := __Map_Find_Result{-1, -1, -1}; +__dynamic_map_find :: proc(using h: Map_Header, key: Map_Key) -> Map_Find_Result #no_bounds_check { + fr := Map_Find_Result{-1, -1, -1}; if len(m.hashes) > 0 { fr.hash_index = int(key.hash % u64(len(m.hashes))); fr.entry_index = m.hashes[fr.hash_index]; @@ -742,7 +731,7 @@ __dynamic_map_find :: proc(using h: __Map_Header, key: __Map_Key) -> __Map_Find_ return fr; } -__dynamic_map_add_entry :: proc(using h: __Map_Header, key: __Map_Key, loc := #caller_location) -> int { +__dynamic_map_add_entry :: proc(using h: Map_Header, key: Map_Key, loc := #caller_location) -> int { prev := m.entries.len; c := __dynamic_array_append_nothing(&m.entries, entry_size, entry_align, loc); if c != prev { @@ -753,19 +742,19 @@ __dynamic_map_add_entry :: proc(using h: __Map_Header, key: __Map_Key, loc := #c return prev; } -__dynamic_map_delete :: proc(using h: __Map_Header, key: __Map_Key) { +__dynamic_map_delete :: proc(using h: Map_Header, key: Map_Key) { fr := __dynamic_map_find(h, key); if fr.entry_index >= 0 { __dynamic_map_erase(h, fr); } } -__dynamic_map_get_entry :: proc(using h: __Map_Header, index: int) -> ^__Map_Entry_Header { +__dynamic_map_get_entry :: proc(using h: Map_Header, index: int) -> ^Map_Entry_Header { assert(0 <= index && index < m.entries.len); - return (^__Map_Entry_Header)(uintptr(m.entries.data) + uintptr(index*entry_size)); + return (^Map_Entry_Header)(uintptr(m.entries.data) + uintptr(index*entry_size)); } -__dynamic_map_erase :: proc(using h: __Map_Header, fr: __Map_Find_Result) #no_bounds_check { +__dynamic_map_erase :: proc(using h: Map_Header, fr: Map_Find_Result) #no_bounds_check { if fr.entry_prev < 0 { m.hashes[fr.hash_index] = __dynamic_map_get_entry(h, fr.entry_index).next; } else { diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 87d19ab87..7f38bb7ce 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -1,6 +1,5 @@ package runtime -import "core:raw" import "core:mem" import "core:os" import "core:unicode/utf8" @@ -239,7 +238,7 @@ __cstring_to_string :: proc "contextless" (s: cstring) -> string { if s == nil do return ""; ptr := (^byte)(s); n := __cstring_len(s); - return transmute(string)raw.String{ptr, n}; + return transmute(string)mem.Raw_String{ptr, n}; } @@ -250,7 +249,7 @@ __complex128_eq :: inline proc "contextless" (a, b: complex128) -> bool { return __complex128_ne :: inline proc "contextless" (a, b: complex128) -> bool { return real(a) != real(b) || imag(a) != imag(b); } -__bounds_check_error :: proc "contextless" (file: string, line, column: int, index, count: int) { +bounds_check_error :: proc "contextless" (file: string, line, column: int, index, count: int) { if 0 <= index && index < count do return; fd := os.stderr; @@ -263,7 +262,7 @@ __bounds_check_error :: proc "contextless" (file: string, line, column: int, ind __debug_trap(); } -__slice_expr_error :: proc "contextless" (file: string, line, column: int, lo, hi: int, len: int) { +slice_expr_error :: proc "contextless" (file: string, line, column: int, lo, hi: int, len: int) { if 0 <= lo && lo <= hi && hi <= len do return; @@ -279,7 +278,7 @@ __slice_expr_error :: proc "contextless" (file: string, line, column: int, lo, h __debug_trap(); } -__dynamic_array_expr_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) { +dynamic_array_expr_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) { if 0 <= low && low <= high && high <= max do return; fd := os.stderr; @@ -294,7 +293,7 @@ __dynamic_array_expr_error :: proc "contextless" (file: string, line, column: in __debug_trap(); } -__type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: int, from, to: typeid) { +type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: int, from, to: typeid) { if ok do return; fd := os.stderr; @@ -311,11 +310,12 @@ __string_decode_rune :: inline proc "contextless" (s: string) -> (rune, int) { return utf8.decode_rune_from_string(s); } -__bounds_check_error_loc :: inline proc "contextless" (using loc := #caller_location, index, count: int) { - __bounds_check_error(file_path, int(line), int(column), index, count); +bounds_check_error_loc :: inline proc "contextless" (using loc := #caller_location, index, count: int) { + bounds_check_error(file_path, int(line), int(column), index, count); } -__slice_expr_error_loc :: inline proc "contextless" (using loc := #caller_location, lo, hi: int, len: int) { - __slice_expr_error(file_path, int(line), int(column), lo, hi, len); + +slice_expr_error_loc :: inline proc "contextless" (using loc := #caller_location, lo, hi: int, len: int) { + slice_expr_error(file_path, int(line), int(column), lo, hi, len); } diff --git a/core/runtime/soft_numbers.odin b/core/runtime/soft_numbers.odin deleted file mode 100644 index 92ec2bfec..000000000 --- a/core/runtime/soft_numbers.odin +++ /dev/null @@ -1,112 +0,0 @@ -package runtime - -/* -@(link_name="__multi3") -__multi3 :: proc "c" (a, b: u128) -> u128 { - bits_in_dword_2 :: size_of(i64) * 4; - lower_mask :: u128(~u64(0) >> bits_in_dword_2); - - - when ODIN_ENDIAN == "big" { - TWords :: struct #raw_union { - all: u128, - using _: struct {lo, hi: u64}, - }; - } else { - TWords :: struct #raw_union { - all: u128, - using _: struct {hi, lo: u64}, - }; - } - - r: TWords; - t: u64; - - r.lo = u64(a & lower_mask) * u64(b & lower_mask); - t = r.lo >> bits_in_dword_2; - r.lo &= u64(lower_mask); - t += u64(a >> bits_in_dword_2) * u64(b & lower_mask); - r.lo += u64(t & u64(lower_mask)) << bits_in_dword_2; - r.hi = t >> bits_in_dword_2; - t = r.lo >> bits_in_dword_2; - r.lo &= u64(lower_mask); - t += u64(b >> bits_in_dword_2) * u64(a & lower_mask); - r.lo += u64(t & u64(lower_mask)) << bits_in_dword_2; - r.hi += t >> bits_in_dword_2; - r.hi += u64(a >> bits_in_dword_2) * u64(b >> bits_in_dword_2); - return r.all; -} - -@(link_name="__umodti3") -__u128_mod :: proc "c" (a, b: u128) -> u128 { - r: u128; - __u128_quo_mod(a, b, &r); - return r; -} - -@(link_name="__udivti3") -__u128_quo :: proc "c" (a, b: u128) -> u128 { - return __u128_quo_mod(a, b, nil); -} - -@(link_name="__modti3") -__i128_mod :: proc "c" (a, b: i128) -> i128 { - r: i128; - __i128_quo_mod(a, b, &r); - return r; -} - -@(link_name="__divti3") -__i128_quo :: proc "c" (a, b: i128) -> i128 { - return __i128_quo_mod(a, b, nil); -} - -@(link_name="__divmodti4") -__i128_quo_mod :: proc "c" (a, b: i128, rem: ^i128) -> (quo: i128) { - s: i128; - s = b >> 127; - b = (b~s) - s; - s = a >> 127; - b = (a~s) - s; - - uquo: u128; - urem := __u128_quo_mod(transmute(u128)a, transmute(u128)b, &uquo); - iquo := transmute(i128)uquo; - irem := transmute(i128)urem; - - iquo = (iquo~s) - s; - irem = (irem~s) - s; - if rem != nil do rem^ = irem; - return iquo; -} - - -@(link_name="__udivmodti4") -__u128_quo_mod :: proc "c" (a, b: u128, rem: ^u128) -> (quo: u128) { - alo := u64(a); - blo := u64(b); - if b == 0 { - if rem != nil do rem^ = 0; - return u128(alo/blo); - } - - r, d, x, q: u128 = a, b, 1, 0; - - for r >= d && (d>>127)&1 == 0 { - x <<= 1; - d <<= 1; - } - - for x != 0 { - if r >= d { - r -= d; - q |= x; - } - x >>= 1; - d >>= 1; - } - - if rem != nil do rem^ = r; - return q; -} -*/ diff --git a/core/sort/sort.odin b/core/sort/sort.odin index f2e349b61..b69102b8e 100644 --- a/core/sort/sort.odin +++ b/core/sort/sort.odin @@ -1,5 +1,7 @@ package sort +import "core:mem" + bubble_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) { assert(f != nil); count := len(array); @@ -211,5 +213,5 @@ compare_f64s :: proc(a, b: f64) -> int { return 0; } compare_strings :: proc(a, b: string) -> int { - return __string_cmp(a, b); + return mem.compare_byte_ptrs(&a[0], &b[0], min(len(a), len(b))); } diff --git a/core/strings/strings.odin b/core/strings/strings.odin index acbd3f054..89395e2bb 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -1,6 +1,6 @@ package strings -import "core:raw" +import "core:mem" new_string :: proc(s: string) -> string { c := make([]byte, len(s)+1); @@ -22,7 +22,7 @@ to_odin_string :: proc(str: cstring) -> string { } string_from_ptr :: proc(ptr: ^byte, len: int) -> string { - return transmute(string)raw.String{ptr, len}; + return transmute(string)mem.Raw_String{ptr, len}; } contains_rune :: proc(s: string, r: rune) -> int { diff --git a/core/thread/thread_windows.odin b/core/thread/thread_windows.odin index adf59b898..369a61072 100644 --- a/core/thread/thread_windows.odin +++ b/core/thread/thread_windows.odin @@ -1,5 +1,6 @@ package thread +import "core:runtime" import "core:sys/win32" Thread_Proc :: #type proc(^Thread) -> int; @@ -15,7 +16,7 @@ Thread :: struct { data: rawptr, user_index: int, - init_context: Context, + init_context: runtime.Context, use_init_context: bool, } diff --git a/core/types/types.odin b/core/types/types.odin index ff892199d..853e9dc25 100644 --- a/core/types/types.odin +++ b/core/types/types.odin @@ -1,6 +1,8 @@ package types -are_types_identical :: proc(a, b: ^Type_Info) -> bool { +import "core:runtime" + +are_types_identical :: proc(a, b: ^runtime.Type_Info) -> bool { if a == b do return true; if (a == nil && b != nil) || @@ -15,47 +17,47 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { } switch x in a.variant { - case Type_Info_Named: - y, ok := b.variant.(Type_Info_Named); + case runtime.Type_Info_Named: + y, ok := b.variant.(runtime.Type_Info_Named); if !ok do return false; return x.base == y.base; - case Type_Info_Integer: - y, ok := b.variant.(Type_Info_Integer); + case runtime.Type_Info_Integer: + y, ok := b.variant.(runtime.Type_Info_Integer); if !ok do return false; return x.signed == y.signed; - case Type_Info_Rune: - _, ok := b.variant.(Type_Info_Rune); + case runtime.Type_Info_Rune: + _, ok := b.variant.(runtime.Type_Info_Rune); return ok; - case Type_Info_Float: - _, ok := b.variant.(Type_Info_Float); + case runtime.Type_Info_Float: + _, ok := b.variant.(runtime.Type_Info_Float); return ok; - case Type_Info_Complex: - _, ok := b.variant.(Type_Info_Complex); + case runtime.Type_Info_Complex: + _, ok := b.variant.(runtime.Type_Info_Complex); return ok; - case Type_Info_String: - _, ok := b.variant.(Type_Info_String); + case runtime.Type_Info_String: + _, ok := b.variant.(runtime.Type_Info_String); return ok; - case Type_Info_Boolean: - _, ok := b.variant.(Type_Info_Boolean); + case runtime.Type_Info_Boolean: + _, ok := b.variant.(runtime.Type_Info_Boolean); return ok; - case Type_Info_Any: - _, ok := b.variant.(Type_Info_Any); + case runtime.Type_Info_Any: + _, ok := b.variant.(runtime.Type_Info_Any); return ok; - case Type_Info_Pointer: - y, ok := b.variant.(Type_Info_Pointer); + case runtime.Type_Info_Pointer: + y, ok := b.variant.(runtime.Type_Info_Pointer); if !ok do return false; return are_types_identical(x.elem, y.elem); - case Type_Info_Procedure: - y, ok := b.variant.(Type_Info_Procedure); + case runtime.Type_Info_Procedure: + y, ok := b.variant.(runtime.Type_Info_Procedure); if !ok do return false; switch { case x.variadic != y.variadic, @@ -65,24 +67,24 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { return are_types_identical(x.params, y.params) && are_types_identical(x.results, y.results); - case Type_Info_Array: - y, ok := b.variant.(Type_Info_Array); + case runtime.Type_Info_Array: + y, ok := b.variant.(runtime.Type_Info_Array); if !ok do return false; if x.count != y.count do return false; return are_types_identical(x.elem, y.elem); - case Type_Info_Dynamic_Array: - y, ok := b.variant.(Type_Info_Dynamic_Array); + case runtime.Type_Info_Dynamic_Array: + y, ok := b.variant.(runtime.Type_Info_Dynamic_Array); if !ok do return false; return are_types_identical(x.elem, y.elem); - case Type_Info_Slice: - y, ok := b.variant.(Type_Info_Slice); + case runtime.Type_Info_Slice: + y, ok := b.variant.(runtime.Type_Info_Slice); if !ok do return false; return are_types_identical(x.elem, y.elem); - case Type_Info_Tuple: - y, ok := b.variant.(Type_Info_Tuple); + case runtime.Type_Info_Tuple: + y, ok := b.variant.(runtime.Type_Info_Tuple); if !ok do return false; if len(x.types) != len(y.types) do return false; for _, i in x.types { @@ -93,8 +95,8 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { } return true; - case Type_Info_Struct: - y, ok := b.variant.(Type_Info_Struct); + case runtime.Type_Info_Struct: + y, ok := b.variant.(runtime.Type_Info_Struct); if !ok do return false; switch { case len(x.types) != len(y.types), @@ -112,8 +114,8 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { } return true; - case Type_Info_Union: - y, ok := b.variant.(Type_Info_Union); + case runtime.Type_Info_Union: + y, ok := b.variant.(runtime.Type_Info_Union); if !ok do return false; if len(x.variants) != len(y.variants) do return false; @@ -123,17 +125,17 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { } return true; - case Type_Info_Enum: + case runtime.Type_Info_Enum: // NOTE(bill): Should be handled above return false; - case Type_Info_Map: - y, ok := b.variant.(Type_Info_Map); + case runtime.Type_Info_Map: + y, ok := b.variant.(runtime.Type_Info_Map); if !ok do return false; return are_types_identical(x.key, y.key) && are_types_identical(x.value, y.value); - case Type_Info_Bit_Field: - y, ok := b.variant.(Type_Info_Bit_Field); + case runtime.Type_Info_Bit_Field: + y, ok := b.variant.(runtime.Type_Info_Bit_Field); if !ok do return false; if len(x.names) != len(y.names) do return false; @@ -154,101 +156,101 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { } -is_signed :: proc(info: ^Type_Info) -> bool { +is_signed :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - switch i in type_info_base(info).variant { - case Type_Info_Integer: return i.signed; - case Type_Info_Float: return true; + switch i in runtime.type_info_base(info).variant { + case runtime.Type_Info_Integer: return i.signed; + case runtime.Type_Info_Float: return true; } return false; } -is_integer :: proc(info: ^Type_Info) -> bool { +is_integer :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Integer); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Integer); return ok; } -is_rune :: proc(info: ^Type_Info) -> bool { +is_rune :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Rune); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Rune); return ok; } -is_float :: proc(info: ^Type_Info) -> bool { +is_float :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Float); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Float); return ok; } -is_complex :: proc(info: ^Type_Info) -> bool { +is_complex :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Complex); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Complex); return ok; } -is_any :: proc(info: ^Type_Info) -> bool { +is_any :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Any); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Any); return ok; } -is_string :: proc(info: ^Type_Info) -> bool { +is_string :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_String); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_String); return ok; } -is_boolean :: proc(info: ^Type_Info) -> bool { +is_boolean :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Boolean); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Boolean); return ok; } -is_pointer :: proc(info: ^Type_Info) -> bool { +is_pointer :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Pointer); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Pointer); return ok; } -is_procedure :: proc(info: ^Type_Info) -> bool { +is_procedure :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Procedure); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Procedure); return ok; } -is_array :: proc(info: ^Type_Info) -> bool { +is_array :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Array); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Array); return ok; } -is_dynamic_array :: proc(info: ^Type_Info) -> bool { +is_dynamic_array :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Dynamic_Array); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Dynamic_Array); return ok; } -is_dynamic_map :: proc(info: ^Type_Info) -> bool { +is_dynamic_map :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Map); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Map); return ok; } -is_slice :: proc(info: ^Type_Info) -> bool { +is_slice :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Slice); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Slice); return ok; } -is_tuple :: proc(info: ^Type_Info) -> bool { +is_tuple :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Tuple); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Tuple); return ok; } -is_struct :: proc(info: ^Type_Info) -> bool { +is_struct :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - s, ok := type_info_base(info).variant.(Type_Info_Struct); + s, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Struct); return ok && !s.is_raw_union; } -is_raw_union :: proc(info: ^Type_Info) -> bool { +is_raw_union :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - s, ok := type_info_base(info).variant.(Type_Info_Struct); + s, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Struct); return ok && s.is_raw_union; } -is_union :: proc(info: ^Type_Info) -> bool { +is_union :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Union); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Union); return ok; } -is_enum :: proc(info: ^Type_Info) -> bool { +is_enum :: proc(info: ^runtime.Type_Info) -> bool { if info == nil do return false; - _, ok := type_info_base(info).variant.(Type_Info_Enum); + _, ok := runtime.type_info_base(info).variant.(runtime.Type_Info_Enum); return ok; } diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index 54a895d0a..fbb6da8c5 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -8,13 +8,13 @@ import "core:hash" import "core:math" import "core:math/rand" import "core:os" -import "core:raw" import "core:sort" import "core:strings" import "core:types" import "core:unicode/utf16" import "core:unicode/utf8" import "core:c" +import "core:runtime" when os.OS == "windows" { import "core:atomics" @@ -352,7 +352,7 @@ parametric_polymorphism :: proc() { TABLE_SIZE_MIN :: 32; Table :: struct(Key, Value: type) { count: int, - allocator: Allocator, + allocator: mem.Allocator, slots: []Table_Slot(Key, Value), } @@ -495,12 +495,12 @@ threading_example :: proc() { fmt.println("# threading_example"); unordered_remove :: proc(array: ^[dynamic]$T, index: int, loc := #caller_location) { - __bounds_check_error_loc(loc, index, len(array)); + runtime.bounds_check_error_loc(loc, index, len(array)); array[index] = array[len(array)-1]; pop(array); } ordered_remove :: proc(array: ^[dynamic]$T, index: int, loc := #caller_location) { - __bounds_check_error_loc(loc, index, len(array)); + runtime.bounds_check_error_loc(loc, index, len(array)); copy(array[index..], array[index+1..]); pop(array); } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 2ae7a3fa1..b2363be38 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4125,7 +4125,6 @@ void check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, o.mode = Addressing_Invalid; } - if (o.type == nullptr || o.type->kind != Type_Tuple) { if (allow_ok && lhs_count == 2 && rhs.count == 1 && (o.mode == Addressing_MapIndex || o.mode == Addressing_OptionalOk)) { @@ -5913,7 +5912,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, AstNode *node, return kind; } - add_package_dependency(c, "runtime", "__type_assertion_check"); + add_package_dependency(c, "runtime", "type_assertion_check"); case_end; case_ast_node(tc, TypeCast, node); @@ -6218,8 +6217,8 @@ ExprKind check_expr_base(CheckerContext *c, Operand *o, AstNode *node, Type *typ type = nullptr; break; case Addressing_Constant: - type = o->type; value = o->value; + type = o->type; break; default: type = o->type; diff --git a/src/checker.cpp b/src/checker.cpp index 9c8a3c0a4..e44697880 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -272,7 +272,6 @@ Scope *create_scope_from_package(CheckerContext *c, AstPackage *p) { if (p->kind == Package_Runtime) { s->is_global = true; - universal_scope->shared = s; } if (s->is_init || s->is_global) { @@ -377,31 +376,7 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit if (s->is_proc) { gone_thru_proc = true; - } else if (s->shared) { - Entity **found = map_get(&s->shared->elements, key); - if (found) { - Entity *e = *found; - if (e->kind == Entity_Variable && - !e->scope->is_file) { - continue; - } - - if (e->scope->parent != s->shared) { - continue; - } - - if ((e->kind == Entity_ImportName || - e->kind == Entity_LibraryName) - && gone_thru_package) { - continue; - } - - if (entity_) *entity_ = e; - if (scope_) *scope_ = s->shared; - return; - } } - if (s->is_package) { gone_thru_package = true; } @@ -511,7 +486,7 @@ void add_package_dependency(CheckerContext *c, char *package_name, char *name) { String n = make_string_c(name); AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); Entity *e = scope_lookup_entity(p->scope, n); - GB_ASSERT(e != nullptr); + GB_ASSERT_MSG(e != nullptr, "%s", name); ptr_set_add(&c->decl->deps, e); // add_type_info_type(c, e->type); } @@ -841,7 +816,7 @@ void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode return; } if (mode == Addressing_Constant && type == t_invalid) { - compiler_error("add_type_and_value - invalid type: %s", type_to_string(type)); + return; } TypeAndValue tv = {}; @@ -939,20 +914,11 @@ void add_entity_and_decl_info(CheckerContext *c, AstNode *identifier, Entity *e, if (e->scope != nullptr) { Scope *scope = e->scope; - if (scope->is_file) { - switch (e->kind) { - case Entity_ImportName: - case Entity_LibraryName: - // NOTE(bill): Entities local to file rather than package - break; - default: { - AstPackage *pkg = scope->file->pkg; - GB_ASSERT(pkg->scope == scope->parent); - GB_ASSERT(c->pkg == pkg); - scope = pkg->scope; - break; - } - } + if (scope->is_file && is_entity_kind_exported(e->kind)) { + AstPackage *pkg = scope->file->pkg; + GB_ASSERT(pkg->scope == scope->parent); + GB_ASSERT(c->pkg == pkg); + scope = pkg->scope; } add_entity(c->checker, scope, identifier, e); } @@ -1346,12 +1312,11 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { String required_builtin_entities[] = { str_lit("__init_context"), - str_lit("__args__"), - str_lit("__type_table"), + str_lit("args__"), + str_lit("type_table"), str_lit("Type_Info"), str_lit("Source_Code_Location"), - str_lit("Allocator"), str_lit("Context"), }; for (isize i = 0; i < gb_count_of(required_builtin_entities); i++) { @@ -1360,18 +1325,27 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { AstPackage *mem = get_core_package(&c->info, str_lit("mem")); String required_mem_entities[] = { - str_lit("default_allocator"), str_lit("zero"), + str_lit("Allocator"), }; for (isize i = 0; i < gb_count_of(required_mem_entities); i++) { add_dependency_to_set(c, scope_lookup_entity(mem->scope, required_mem_entities[i])); } + AstPackage *os = get_core_package(&c->info, str_lit("os")); + String required_os_entities[] = { + str_lit("default_allocator"), + }; + for (isize i = 0; i < gb_count_of(required_os_entities); i++) { + add_dependency_to_set(c, scope_lookup_entity(os->scope, required_mem_entities[i])); + } + + if (!build_context.no_bounds_check) { String bounds_check_entities[] = { - str_lit("__bounds_check_error"), - str_lit("__slice_expr_error"), - str_lit("__dynamic_array_expr_error"), + str_lit("bounds_check_error"), + str_lit("slice_expr_error"), + str_lit("dynamic_array_expr_error"), }; for (isize i = 0; i < gb_count_of(bounds_check_entities); i++) { add_dependency_to_set(c, scope_lookup_entity(c->info.runtime_package->scope, bounds_check_entities[i])); @@ -1497,7 +1471,7 @@ Entity *find_core_entity(Checker *c, String name) { Entity *e = current_scope_lookup_entity(c->info.runtime_package->scope, name); if (e == nullptr) { compiler_error("Could not find type declaration for '%.*s'\n" - "Is '_preload.odin' missing from the 'core' directory relative to odin.exe?", LIT(name)); +, LIT(name)); // NOTE(bill): This will exit the program as it's cannot continue without it! } return e; @@ -1507,7 +1481,7 @@ Type *find_core_type(Checker *c, String name) { Entity *e = current_scope_lookup_entity(c->info.runtime_package->scope, name); if (e == nullptr) { compiler_error("Could not find type declaration for '%.*s'\n" - "Is '_preload.odin' missing from the 'core' directory relative to odin.exe?", LIT(name)); +, LIT(name)); // NOTE(bill): This will exit the program as it's cannot continue without it! } return e->type; @@ -1624,7 +1598,16 @@ void init_core_allocator(Checker *c) { if (t_allocator != nullptr) { return; } - t_allocator = find_core_type(c, str_lit("Allocator")); + AstPackage *pkg = get_core_package(&c->info, str_lit("mem")); + + String name = str_lit("Allocator"); + Entity *e = current_scope_lookup_entity(pkg->scope, name); + if (e == nullptr) { + compiler_error("Could not find type declaration for '%.*s'\n", LIT(name)); + // NOTE(bill): This will exit the program as it's cannot continue without it! + } + + t_allocator = e->type; t_allocator_ptr = alloc_type_pointer(t_allocator); } @@ -1646,11 +1629,11 @@ void init_core_source_code_location(Checker *c) { void init_core_map_type(Checker *c) { if (t_map_key == nullptr) { - t_map_key = find_core_type(c, str_lit("__Map_Key")); + t_map_key = find_core_type(c, str_lit("Map_Key")); } if (t_map_header == nullptr) { - t_map_header = find_core_type(c, str_lit("__Map_Header")); + t_map_header = find_core_type(c, str_lit("Map_Header")); } } @@ -1767,7 +1750,8 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) { ac->thread_local_model = str_lit("default"); } else if (value.kind == ExactValue_String) { String model = value.value_string; - if (model == "localdynamic" || + if (model == "default" || + model == "localdynamic" || model == "initialexec" || model == "localexec") { ac->thread_local_model = model; @@ -1935,6 +1919,66 @@ void check_collect_entities_from_when_stmt(CheckerContext *c, AstNodeWhenStmt *w } } +void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array *attributes) { + switch (e->kind) { + case Entity_ProcGroup: + case Entity_Procedure: + case Entity_TypeName: + // Okay + break; + default: + return; + } + if (!(ctx->scope->is_file && ctx->scope->file->pkg->kind == Package_Runtime)) { + return; + } + + for_array(j, *attributes) { + AstNode *attr = (*attributes)[j]; + if (attr->kind != AstNode_Attribute) continue; + for (isize k = 0; k < attr->Attribute.elems.count; k++) { + AstNode *elem = attr->Attribute.elems[k]; + String name = {}; + AstNode *value = nullptr; + + switch (elem->kind) { + case_ast_node(i, Ident, elem); + name = i->token.string; + case_end; + case_ast_node(fv, FieldValue, elem); + GB_ASSERT(fv->field->kind == AstNode_Ident); + name = fv->field->Ident.token.string; + value = fv->value; + case_end; + default: + continue; + } + + if (name == "builtin") { + add_entity(ctx->checker, universal_scope, nullptr, e); + GB_ASSERT(scope_lookup_entity(universal_scope, e->token.string) != nullptr); + if (value != nullptr) { + error(value, "'builtin' cannot have a field value"); + } + // Remove the builtin tag + attr->Attribute.elems[k] = attr->Attribute.elems[attr->Attribute.elems.count-1]; + attr->Attribute.elems.count -= 1; + k--; + } + } + } + + for (isize i = 0; i < attributes->count; i++) { + AstNode *attr = (*attributes)[i]; + if (attr->kind != AstNode_Attribute) continue; + if (attr->Attribute.elems.count == 0) { + (*attributes)[i] = (*attributes)[attributes->count-1]; + attributes->count--; + i--; + } + } +} + void check_collect_value_decl(CheckerContext *c, AstNode *decl) { ast_node(vd, ValueDecl, decl); @@ -2093,6 +2137,7 @@ void check_collect_value_decl(CheckerContext *c, AstNode *decl) { } } + check_builtin_attributes(c, e, &d->attributes); add_entity_and_decl_info(c, name, e, d); } @@ -2446,6 +2491,11 @@ Array find_import_path(Checker *c, AstPackage *start, AstPackage } GB_ASSERT(pkg != nullptr && pkg->scope != nullptr); + if (pkg->kind == Package_Runtime) { + // NOTE(bill): Allow cyclic imports within the runtime package for the time being + continue; + } + ImportPathItem item = {pkg, decl}; if (pkg == end) { auto path = array_make(heap_allocator()); @@ -2821,6 +2871,7 @@ void check_import_entities(Checker *c) { return item.pkg->name; }; + #if 1 if (path.count == 1) { // TODO(bill): Should this be allowed or disabled? #if 0 @@ -2839,12 +2890,12 @@ void check_import_entities(Checker *c) { } error(item.decl, "'%.*s'", LIT(pkg_name)); } + #endif } for_array(i, n->pred.entries) { ImportGraphNode *p = n->pred.entries[i].ptr; p->dep_count = gb_max(p->dep_count-1, 0); - // p->dep_count -= 1; priority_queue_fix(&pq, p->index); } diff --git a/src/checker.hpp b/src/checker.hpp index fa43219e2..2d294b9e8 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -7,6 +7,7 @@ struct DeclInfo; struct AstFile; struct Checker; struct CheckerInfo; +struct CheckerContext; enum AddressingMode { Addressing_Invalid, // invalid addressing mode @@ -177,6 +178,26 @@ struct BlockLabel { AstNode *label; // AstNode_Label; }; +struct AttributeContext { + String link_name; + String link_prefix; + isize init_expr_list_count; + String thread_local_model; + String deprecated_message; +}; + +AttributeContext make_attribute_context(String link_prefix) { + AttributeContext ac = {}; + ac.link_prefix = link_prefix; + return ac; +} + +#define DECL_ATTRIBUTE_PROC(_name) bool _name(CheckerContext *c, AstNode *elem, String name, ExactValue value, AttributeContext *ac) +typedef DECL_ATTRIBUTE_PROC(DeclAttributeProc); + +void check_decl_attributes(CheckerContext *c, Array const &attributes, DeclAttributeProc *proc, AttributeContext *ac); + + // DeclInfo is used to store information of certain declarations to allow for "any order" usage struct DeclInfo { DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment @@ -218,7 +239,7 @@ struct Scope { Scope * last_child; Map elements; // Key: String PtrSet implicit; - Scope * shared; + // Scope * shared; Array delayed_directives; Array delayed_imports; @@ -392,25 +413,6 @@ void check_collect_entities(CheckerContext *c, Array const &nodes); void check_collect_entities_from_when_stmt(CheckerContext *c, AstNodeWhenStmt *ws); void check_delayed_file_import_entity(CheckerContext *c, AstNode *decl); -struct AttributeContext { - String link_name; - String link_prefix; - isize init_expr_list_count; - String thread_local_model; - String deprecated_message; -}; - -AttributeContext make_attribute_context(String link_prefix) { - AttributeContext ac = {}; - ac.link_prefix = link_prefix; - return ac; -} - -#define DECL_ATTRIBUTE_PROC(_name) bool _name(CheckerContext *c, AstNode *elem, String name, ExactValue value, AttributeContext *ac) -typedef DECL_ATTRIBUTE_PROC(DeclAttributeProc); - -void check_decl_attributes(CheckerContext *c, Array const &attributes, DeclAttributeProc *proc, AttributeContext *ac); - CheckerTypePath *new_checker_type_path(); void destroy_checker_type_path(CheckerTypePath *tp); diff --git a/src/common.cpp b/src/common.cpp index 1a9a4e363..82a1685c4 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -40,13 +40,13 @@ GB_ALLOCATOR_PROC(heap_allocator_proc); gbAllocator heap_allocator(void) { gbAllocator a; a.proc = heap_allocator_proc; - a.data = NULL; + a.data = nullptr; return a; } GB_ALLOCATOR_PROC(heap_allocator_proc) { - void *ptr = NULL; + void *ptr = nullptr; gb_unused(allocator_data); gb_unused(old_size); @@ -348,7 +348,7 @@ void *pool_alloc(Pool *pool, isize size, isize align) { } GB_ALLOCATOR_PROC(pool_allocator_proc) { - void *ptr = NULL; + void *ptr = nullptr; Pool *pool = cast(Pool *)allocator_data; diff --git a/src/ir.cpp b/src/ir.cpp index 4e670fbd6..a353c6f02 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1534,7 +1534,7 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na // //////////////////////////////////////////////////////////////// -irValue *ir_emit_global_call (irProcedure *proc, char const *name_, Array args, AstNode *expr = nullptr); +irValue *ir_emit_runtime_call (irProcedure *proc, char const *name_, Array args, AstNode *expr = nullptr); irValue *ir_emit_package_call(irProcedure *proc, char const *package_name_, char const *name_, Array args, AstNode *expr = nullptr); @@ -1593,7 +1593,7 @@ void ir_emit_init_context(irProcedure *proc, irValue *c = nullptr) { gbAllocator a = m->allocator; auto args = array_make(a, 1); args[0] = c ? c : m->global_default_context; - ir_emit_global_call(proc, "__init_context", args); + ir_emit_runtime_call(proc, "__init_context", args); } @@ -1637,7 +1637,7 @@ irValue *ir_find_or_generate_context_ptr(irProcedure *proc) { irValue *ep = ir_emit_struct_ep(proc, c, 0); Array args = {}; - irValue *v = ir_emit_package_call(proc, "mem", "default_allocator", args); + irValue *v = ir_emit_package_call(proc, "os", "default_allocator", args); ir_emit_store(proc, ep, v); return c; @@ -1702,7 +1702,7 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, Array args) { return result; } -irValue *ir_emit_global_call(irProcedure *proc, char const *name_, Array args, AstNode *expr) { +irValue *ir_emit_runtime_call(irProcedure *proc, char const *name_, Array args, AstNode *expr) { String name = make_string_c(cast(char *)name_); AstPackage *p = proc->module->info->runtime_package; @@ -1879,7 +1879,7 @@ irValue *ir_gen_map_key(irProcedure *proc, irValue *key, Type *key_type) { } else { auto args = array_make(proc->module->allocator, 1); args[0] = str; - hashed_str = ir_emit_global_call(proc, "__default_hash_string", args); + hashed_str = ir_emit_runtime_call(proc, "__default_hash_string", args); } ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), hashed_str); ir_emit_store(proc, ir_emit_struct_ep(proc, v, 1), str); @@ -1941,7 +1941,7 @@ irValue *ir_insert_dynamic_map_key_and_value(irProcedure *proc, irValue *addr, T args[1] = key; args[2] = ir_emit_conv(proc, ptr, t_rawptr); args[3] = ir_emit_source_code_location(proc, nullptr); - return ir_emit_global_call(proc, "__dynamic_map_set", args); + return ir_emit_runtime_call(proc, "__dynamic_map_set", args); } @@ -2041,7 +2041,7 @@ irValue *ir_addr_load(irProcedure *proc, irAddr const &addr) { args[0] = h; args[1] = key; - irValue *ptr = ir_emit_global_call(proc, "__dynamic_map_get", args); + irValue *ptr = ir_emit_runtime_call(proc, "__dynamic_map_get", args); irValue *ok = ir_emit_conv(proc, ir_emit_comp(proc, Token_NotEq, ptr, v_raw_nil), t_bool); ir_emit_store(proc, ir_emit_struct_ep(proc, v, 1), ok); @@ -2543,7 +2543,7 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal auto args = array_make(proc->module->allocator, 2); args[0] = left; args[1] = right; - return ir_emit_global_call(proc, runtime_proc, args); + return ir_emit_runtime_call(proc, runtime_proc, args); } if (is_type_complex(a)) { @@ -2568,7 +2568,7 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal auto args = array_make(proc->module->allocator, 2); args[0] = left; args[1] = right; - return ir_emit_global_call(proc, runtime_proc, args); + return ir_emit_runtime_call(proc, runtime_proc, args); } @@ -2893,7 +2893,7 @@ irValue *ir_cstring_len(irProcedure *proc, irValue *value) { GB_ASSERT(is_type_cstring(ir_type(value))); auto args = array_make(proc->module->allocator, 1); args[0] = ir_emit_conv(proc, value, t_cstring); - return ir_emit_global_call(proc, "__cstring_len", args); + return ir_emit_runtime_call(proc, "__cstring_len", args); } @@ -3140,7 +3140,7 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { irValue *c = ir_emit_conv(proc, value, t_cstring); auto args = array_make(proc->module->allocator, 1); args[0] = c; - irValue *s = ir_emit_global_call(proc, "__cstring_to_string", args); + irValue *s = ir_emit_runtime_call(proc, "__cstring_to_string", args); return ir_emit_conv(proc, s, dst); } @@ -3161,13 +3161,13 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { // case 4: { // auto args = array_make(proc->module->allocator, 1); // args[0] = value; - // return ir_emit_global_call(proc, "__gnu_h2f_ieee", args); + // return ir_emit_runtime_call(proc, "__gnu_h2f_ieee", args); // break; // } // case 8: { // auto args = array_make(proc->module->allocator, 1); // args[0] = value; - // return ir_emit_global_call(proc, "__f16_to_f64", args); + // return ir_emit_runtime_call(proc, "__f16_to_f64", args); // break; // } // } @@ -3177,13 +3177,13 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { // case 4: { // auto args = array_make(proc->module->allocator, 1); // args[0] = value; - // return ir_emit_global_call(proc, "__gnu_f2h_ieee", args); + // return ir_emit_runtime_call(proc, "__gnu_f2h_ieee", args); // break; // } // case 8: { // auto args = array_make(proc->module->allocator, 1); // args[0] = value; - // return ir_emit_global_call(proc, "__truncdfhf2", args); + // return ir_emit_runtime_call(proc, "__truncdfhf2", args); // break; // } // } @@ -3509,7 +3509,7 @@ irValue *ir_emit_union_cast(irProcedure *proc, irValue *value, Type *type, Token args[4] = ir_typeid(proc->module, src_type); args[5] = ir_typeid(proc->module, dst_type); - ir_emit_global_call(proc, "__type_assertion_check", args); + ir_emit_runtime_call(proc, "type_assertion_check", args); } return ir_emit_load(proc, ir_emit_struct_ep(proc, v, 0)); @@ -3569,7 +3569,7 @@ irAddr ir_emit_any_cast_addr(irProcedure *proc, irValue *value, Type *type, Toke args[4] = any_typeid; args[5] = dst_typeid; - ir_emit_global_call(proc, "__type_assertion_check", args); + ir_emit_runtime_call(proc, "type_assertion_check", args); return ir_addr(ir_emit_struct_ep(proc, v, 0)); } @@ -3713,7 +3713,7 @@ void ir_emit_bounds_check(irProcedure *proc, Token token, irValue *index, irValu args[3] = index; args[4] = len; - ir_emit_global_call(proc, "__bounds_check_error", args); + ir_emit_runtime_call(proc, "bounds_check_error", args); } void ir_emit_slice_bounds_check(irProcedure *proc, Token token, irValue *low, irValue *high, irValue *len, bool is_substring) { @@ -3739,7 +3739,7 @@ void ir_emit_slice_bounds_check(irProcedure *proc, Token token, irValue *low, ir args[4] = high; args[5] = len; - ir_emit_global_call(proc, "__slice_expr_error", args); + ir_emit_runtime_call(proc, "slice_expr_error", args); } void ir_emit_dynamic_array_bounds_check(irProcedure *proc, Token token, irValue *low, irValue *high, irValue *max) { @@ -3765,7 +3765,7 @@ void ir_emit_dynamic_array_bounds_check(irProcedure *proc, Token token, irValue args[4] = high; args[5] = max; - ir_emit_global_call(proc, "__dynamic_array_expr_error", args); + ir_emit_runtime_call(proc, "dynamic_array_expr_error", args); } @@ -4062,8 +4062,8 @@ irValue *ir_emit_min(irProcedure *proc, Type *t, irValue *x, irValue *y) { args[0] = x; args[1] = y; switch (sz) { - case 32: return ir_emit_global_call(proc, "__min_f32", args); - case 64: return ir_emit_global_call(proc, "__min_f64", args); + case 32: return ir_emit_runtime_call(proc, "__min_f32", args); + case 64: return ir_emit_runtime_call(proc, "__min_f64", args); } GB_PANIC("Unknown float type"); } @@ -4080,8 +4080,8 @@ irValue *ir_emit_max(irProcedure *proc, Type *t, irValue *x, irValue *y) { args[0] = x; args[1] = y; switch (sz) { - case 32: return ir_emit_global_call(proc, "__max_f32", args); - case 64: return ir_emit_global_call(proc, "__max_f64", args); + case 32: return ir_emit_runtime_call(proc, "__max_f32", args); + case 64: return ir_emit_runtime_call(proc, "__max_f64", args); } GB_PANIC("Unknown float type"); } @@ -4221,7 +4221,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv auto args = array_make(proc->module->allocator, 1); args[0] = ir_build_expr(proc, arg); - return ir_emit_global_call(proc, "__type_info_of", args); + return ir_emit_runtime_call(proc, "__type_info_of", args); } case BuiltinProc_typeid_of: { @@ -4236,7 +4236,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv auto args = array_make(proc->module->allocator, 1); args[0] = ir_emit_conv(proc, ir_build_expr(proc, arg), t_type_info_ptr); - return ir_emit_global_call(proc, "__typeid_of", args); + return ir_emit_runtime_call(proc, "__typeid_of", args); } case BuiltinProc_len: { @@ -4315,7 +4315,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv irValue **args = gb_alloc_array(a, irValue *, 2); args[0] = ir_const_int(a, size); args[1] = ir_const_int(a, align); - irValue *call = ir_emit_global_call(proc, "alloc", args, 2); + irValue *call = ir_emit_runtime_call(proc, "alloc", args, 2); irValue *v = ir_emit_conv(proc, call, ptr_type); if (type != allocation_type) { Type *u = base_type(allocation_type); @@ -4387,7 +4387,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv args[0] = header; args[1] = cap; args[2] = ir_emit_source_code_location(proc, ce->args[0]); - ir_emit_global_call(proc, "__dynamic_map_reserve", args); + ir_emit_runtime_call(proc, "__dynamic_map_reserve", args); return ir_emit_load(proc, map); } else if (is_type_dynamic_array(type)) { @@ -4412,7 +4412,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv args[3] = len; args[4] = cap; args[5] = ir_emit_source_code_location(proc, ce->args[0]); - ir_emit_global_call(proc, "__dynamic_array_make", args); + ir_emit_runtime_call(proc, "__dynamic_array_make", args); return ir_emit_load(proc, array); } break; @@ -4438,7 +4438,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv irValue **args = gb_alloc_array(a, irValue *, 1); args[0] = da_allocator; args[1] = ptr; - return ir_emit_global_call(proc, "free_ptr_with_allocator", args, 2); + return ir_emit_runtime_call(proc, "free_ptr_with_allocator", args, 2); } else if (is_type_map(type)) { irValue *map = ir_build_expr(proc, node); irValue *map_ptr = ir_address_from_load_or_generate_local(proc, map); @@ -4453,7 +4453,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv irValue **args = gb_alloc_array(a, irValue *, 1); args[0] = da_allocator; args[1] = da_ptr; - ir_emit_global_call(proc, "free_ptr_with_allocator", args, 2); + ir_emit_runtime_call(proc, "free_ptr_with_allocator", args, 2); } { irValue *array = ir_emit_struct_ep(proc, map_ptr, 1); @@ -4465,7 +4465,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv irValue **args = gb_alloc_array(a, irValue *, 1); args[0] = da_allocator; args[1] = da_ptr; - ir_emit_global_call(proc, "free_ptr_with_allocator", args, 2); + ir_emit_runtime_call(proc, "free_ptr_with_allocator", args, 2); } return nullptr; } @@ -4490,7 +4490,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv irValue **args = gb_alloc_array(a, irValue *, 1); args[0] = ptr; - return ir_emit_global_call(proc, "free_ptr", args, 1); + return ir_emit_runtime_call(proc, "free_ptr", args, 1); break; } #endif @@ -4519,12 +4519,12 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv args[1] = elem_size; args[2] = elem_align; args[3] = capacity; - return ir_emit_global_call(proc, "__dynamic_array_reserve", args, 4); + return ir_emit_runtime_call(proc, "__dynamic_array_reserve", args, 4); } else if (is_type_map(type)) { irValue **args = gb_alloc_array(a, irValue *, 2); args[0] = ir_gen_map_header(proc, ptr, type); args[1] = capacity; - return ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2); + return ir_emit_runtime_call(proc, "__dynamic_map_reserve", args, 2); } else { GB_PANIC("Unknown type for 'reserve'"); } @@ -4664,9 +4664,9 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv daa_args[4] = ir_emit_conv(proc, item_count, t_int); if (is_slice) { - return ir_emit_global_call(proc, "__slice_append", daa_args, 5); + return ir_emit_runtime_call(proc, "__slice_append", daa_args, 5); } - return ir_emit_global_call(proc, "__dynamic_array_append", daa_args, 5); + return ir_emit_runtime_call(proc, "__dynamic_array_append", daa_args, 5); break; } #endif @@ -4685,7 +4685,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv irValue **args = gb_alloc_array(a, irValue *, 2); args[0] = ir_gen_map_header(proc, addr, map_type); args[1] = ir_gen_map_key(proc, key, key_type); - return ir_emit_global_call(proc, "__dynamic_map_delete", args, 2); + return ir_emit_runtime_call(proc, "__dynamic_map_delete", args, 2); break; } #endif @@ -4806,8 +4806,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv auto args = array_make(proc->module->allocator, 1); args[0] = x; switch (sz) { - case 64: return ir_emit_global_call(proc, "__abs_complex64", args); - case 128: return ir_emit_global_call(proc, "__abs_complex128", args); + case 64: return ir_emit_runtime_call(proc, "__abs_complex64", args); + case 128: return ir_emit_runtime_call(proc, "__abs_complex128", args); } GB_PANIC("Unknown complex type"); } else if (is_type_float(t)) { @@ -4815,8 +4815,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv auto args = array_make(proc->module->allocator, 1); args[0] = x; switch (sz) { - case 32: return ir_emit_global_call(proc, "__abs_f32", args); - case 64: return ir_emit_global_call(proc, "__abs_f64", args); + case 32: return ir_emit_runtime_call(proc, "__abs_f32", args); + case 64: return ir_emit_runtime_call(proc, "__abs_f64", args); } GB_PANIC("Unknown float type"); } @@ -5053,7 +5053,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) { args[4] = ir_typeid(proc->module, src_type); args[5] = ir_typeid(proc->module, dst_type); - ir_emit_global_call(proc, "__type_assertion_check", args); + ir_emit_runtime_call(proc, "type_assertion_check", args); irValue *data_ptr = v; return ir_emit_conv(proc, data_ptr, tv.type); @@ -5078,7 +5078,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) { args[4] = any_id; args[5] = id; - ir_emit_global_call(proc, "__type_assertion_check", args); + ir_emit_runtime_call(proc, "type_assertion_check", args); return ir_emit_conv(proc, data_ptr, tv.type); } else { @@ -5917,7 +5917,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { args[0] = ir_gen_map_header(proc, v, type); args[1] = ir_const_int(a, 2*cl->elems.count); args[2] = ir_emit_source_code_location(proc, proc_name, pos); - ir_emit_global_call(proc, "__dynamic_map_reserve", args); + ir_emit_runtime_call(proc, "__dynamic_map_reserve", args); } for_array(field_index, cl->elems) { AstNode *elem = cl->elems[field_index]; @@ -5945,7 +5945,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { args[2] = align; args[3] = ir_const_int(a, 2*cl->elems.count); args[4] = ir_emit_source_code_location(proc, proc_name, pos); - ir_emit_global_call(proc, "__dynamic_array_reserve", args); + ir_emit_runtime_call(proc, "__dynamic_array_reserve", args); } i64 item_count = cl->elems.count; @@ -5966,7 +5966,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { args[3] = ir_emit_conv(proc, items, t_rawptr); args[4] = ir_const_int(a, item_count); args[5] = ir_emit_source_code_location(proc, proc_name, pos); - ir_emit_global_call(proc, "__dynamic_array_append", args); + ir_emit_runtime_call(proc, "__dynamic_array_append", args); } break; } @@ -6490,7 +6490,7 @@ void ir_build_range_string(irProcedure *proc, irValue *expr, Type *val_type, irValue *str_len = ir_emit_arith(proc, Token_Sub, count, offset, t_int); auto args = array_make(proc->module->allocator, 1); args[0] = ir_emit_string(proc, str_elem, str_len); - irValue *rune_and_len = ir_emit_global_call(proc, "__string_decode_rune", args); + irValue *rune_and_len = ir_emit_runtime_call(proc, "__string_decode_rune", args); irValue *len = ir_emit_struct_ev(proc, rune_and_len, 1); ir_emit_store(proc, offset_, ir_emit_arith(proc, Token_Add, offset, len, t_int)); @@ -7869,7 +7869,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info CheckerInfo *info = m->info; if (true) { - irValue *global_type_table = ir_find_global_variable(proc, str_lit("__type_table")); + irValue *global_type_table = ir_find_global_variable(proc, str_lit("type_table")); Type *type = base_type(type_deref(ir_type(ir_global_type_info_data))); GB_ASSERT(is_type_array(type)); irValue *len = ir_const_int(proc->module->allocator, type->Array.count); @@ -8657,7 +8657,7 @@ void ir_gen_tree(irGen *s) { irValue *argc = ir_emit_load(proc, *map_get(&proc->module->values, hash_entity(proc_params->Tuple.variables[0]))); irValue *argv = ir_emit_load(proc, *map_get(&proc->module->values, hash_entity(proc_params->Tuple.variables[1]))); - irValue *global_args = ir_find_global_variable(proc, str_lit("__args__")); + irValue *global_args = ir_find_global_variable(proc, str_lit("args__")); ir_fill_slice(proc, global_args, argv, ir_emit_conv(proc, argc, t_int)); @@ -8714,7 +8714,7 @@ void ir_gen_tree(irGen *s) { e->Procedure.link_name = name; ir_begin_procedure_body(proc); - ir_emit_global_call(proc, "main", nullptr, 0); + ir_emit_runtime_call(proc, "main", nullptr, 0); ir_emit_return(proc, v_one32); ir_end_procedure_body(proc); } diff --git a/src/parser.cpp b/src/parser.cpp index 2aeb98706..07996433a 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3680,7 +3680,8 @@ AstNode *parse_stmt(AstFile *f) { elems = array_make(heap_allocator()); while (f->curr_token.kind != Token_CloseParen && f->curr_token.kind != Token_EOF) { - AstNode *elem = parse_ident(f); + AstNode *elem = nullptr; + elem = parse_ident(f); if (f->curr_token.kind == Token_Eq) { Token eq = expect_token(f, Token_Eq); AstNode *value = parse_value(f);