mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-19 04:50:29 +00:00
Fix _preload.odin; Add for in without parameters; Change sync.Mutex for windows
This commit is contained in:
@@ -133,7 +133,8 @@ Allocator :: struct #ordered {
|
||||
|
||||
|
||||
Context :: struct #ordered {
|
||||
thread_id: int,
|
||||
thread_guid: int,
|
||||
thread_index: int,
|
||||
|
||||
allocator: Allocator,
|
||||
|
||||
@@ -229,8 +230,8 @@ __init_context_from_ptr :: proc(c: ^Context, other: ^Context) #cc_contextless {
|
||||
if c.allocator.procedure == nil {
|
||||
c.allocator = default_allocator();
|
||||
}
|
||||
if c.thread_id == 0 {
|
||||
c.thread_id = os.current_thread_id();
|
||||
if c.thread_guid == 0 {
|
||||
c.thread_guid = os.current_thread_id();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,8 +241,8 @@ __init_context :: proc(c: ^Context) #cc_contextless {
|
||||
if c.allocator.procedure == nil {
|
||||
c.allocator = default_allocator();
|
||||
}
|
||||
if c.thread_id == 0 {
|
||||
c.thread_id = os.current_thread_id();
|
||||
if c.thread_guid == 0 {
|
||||
c.thread_guid = os.current_thread_id();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +329,7 @@ append :: proc(array: ^[dynamic]$T, args: ...T) -> int {
|
||||
|
||||
pop :: proc(array: ^[]$T) -> T #cc_contextless {
|
||||
res: T;
|
||||
if array do return res;
|
||||
if array != nil do return res;
|
||||
assert(len(array) > 0);
|
||||
res = array[len(array)-1];
|
||||
^raw.Slice(array).len -= 1;
|
||||
@@ -337,7 +338,7 @@ pop :: proc(array: ^[]$T) -> T #cc_contextless {
|
||||
|
||||
pop :: proc(array: ^[dynamic]$T) -> T #cc_contextless {
|
||||
res: T;
|
||||
if array do return res;
|
||||
if array != nil do return res;
|
||||
assert(len(array) > 0);
|
||||
res = array[len(array)-1];
|
||||
^raw.DynamicArray(array).len -= 1;
|
||||
@@ -352,7 +353,7 @@ clear :: proc(array: ^[dynamic]$T) #cc_contextless #inline {
|
||||
}
|
||||
clear :: proc(m: ^map[$K]$V) #cc_contextless #inline {
|
||||
if m == nil do return;
|
||||
raw_map := ^raw.DynamicMap(array);
|
||||
raw_map := ^raw.DynamicMap(m);
|
||||
hashes := ^raw.DynamicArray(&raw_map.hashes);
|
||||
entries := ^raw.DynamicArray(&raw_map.entries);
|
||||
hashes.len = 0;
|
||||
@@ -391,7 +392,8 @@ __get_map_header :: proc(m: ^map[$K]$V) -> __MapHeader #cc_contextless {
|
||||
value: V,
|
||||
}
|
||||
|
||||
header.is_key_string = types.is_string(type_info(K));
|
||||
_, is_string := type_info_base(type_info(K)).(^TypeInfo.String);
|
||||
header.is_key_string = is_string;
|
||||
header.entry_size = size_of(Entry);
|
||||
header.entry_align = align_of(Entry);
|
||||
header.value_offset = offset_of(Entry, value);
|
||||
|
||||
@@ -75,8 +75,8 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn
|
||||
}
|
||||
|
||||
share_mode := u32(win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE);
|
||||
sa: ^win32.Security_Attributes = nil;
|
||||
sa_inherit := win32.Security_Attributes{length = size_of(win32.Security_Attributes), inherit_handle = 1};
|
||||
sa: ^win32.SecurityAttributes = nil;
|
||||
sa_inherit := win32.SecurityAttributes{length = size_of(win32.SecurityAttributes), inherit_handle = 1};
|
||||
if mode&O_CLOEXEC == 0 {
|
||||
sa = &sa_inherit;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,18 @@ Semaphore :: struct {
|
||||
_handle: win32.Handle,
|
||||
}
|
||||
|
||||
/*
|
||||
Mutex :: struct {
|
||||
_semaphore: Semaphore,
|
||||
_counter: i32,
|
||||
_owner: i32,
|
||||
_recursion: i32,
|
||||
}
|
||||
*/
|
||||
|
||||
Mutex :: struct {
|
||||
_critical_section: win32.CriticalSection,
|
||||
}
|
||||
|
||||
current_thread_id :: proc() -> i32 {
|
||||
return i32(win32.get_current_thread_id());
|
||||
@@ -37,6 +43,29 @@ semaphore_wait :: proc(s: ^Semaphore) {
|
||||
}
|
||||
|
||||
|
||||
mutex_init :: proc(m: ^Mutex, spin_count := 0) {
|
||||
win32.initialize_critical_section_and_spin_count(&m._critical_section, u32(spin_count));
|
||||
}
|
||||
|
||||
mutex_destroy :: proc(m: ^Mutex) {
|
||||
win32.delete_critical_section(&m._critical_section);
|
||||
}
|
||||
|
||||
mutex_lock :: proc(m: ^Mutex) {
|
||||
win32.enter_critical_section(&m._critical_section);
|
||||
}
|
||||
|
||||
mutex_try_lock :: proc(m: ^Mutex) -> bool {
|
||||
return win32.try_enter_critical_section(&m._critical_section) != 0;
|
||||
}
|
||||
|
||||
mutex_unlock :: proc(m: ^Mutex) {
|
||||
win32.leave_critical_section(&m._critical_section);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
mutex_init :: proc(m: ^Mutex) {
|
||||
atomics.store(&m._counter, 0);
|
||||
atomics.store(&m._owner, current_thread_id());
|
||||
@@ -90,4 +119,4 @@ mutex_unlock :: proc(m: ^Mutex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@@ -103,7 +103,7 @@ FindData :: struct #ordered {
|
||||
alternate_file_name: [14]u8,
|
||||
}
|
||||
|
||||
Security_Attributes :: struct #ordered {
|
||||
SecurityAttributes :: struct #ordered {
|
||||
length: u32,
|
||||
security_descriptor: rawptr,
|
||||
inherit_handle: Bool,
|
||||
@@ -142,6 +142,30 @@ PixelFormatDescriptor :: struct #ordered {
|
||||
damage_mask: u32,
|
||||
}
|
||||
|
||||
CriticalSection :: struct #ordered {
|
||||
debug_info: ^CriticalSectionDebug,
|
||||
|
||||
lock_count: i32,
|
||||
recursion_count: i32,
|
||||
owning_thread: Handle,
|
||||
lock_semaphore: Handle,
|
||||
spin_count: ^u32,
|
||||
}
|
||||
|
||||
CriticalSectionDebug :: struct #ordered {
|
||||
typ: u16,
|
||||
creator_back_trace_index: u16,
|
||||
critical_section: ^CriticalSection,
|
||||
process_locks_list: ^ListEntry,
|
||||
entry_count: u32,
|
||||
contention_count: u32,
|
||||
flags: u32,
|
||||
creator_back_trace_index_high: u16,
|
||||
spare_word: u16,
|
||||
}
|
||||
|
||||
ListEntry :: struct #ordered {flink, blink: ^ListEntry};
|
||||
|
||||
|
||||
|
||||
MAPVK_VK_TO_VSC :: 0;
|
||||
@@ -154,6 +178,12 @@ MAPVK_VSC_TO_VK_EX :: 3;
|
||||
|
||||
INVALID_HANDLE :: Handle(~int(0));
|
||||
|
||||
CREATE_SUSPENDED :: 0x00000004;
|
||||
STACK_SIZE_PARAM_IS_A_RESERVATION :: 0x00010000;
|
||||
WAIT_ABANDONED :: 0x00000080;
|
||||
WAIT_OBJECT_0 :: 0;
|
||||
WAIT_TIMEOUT :: 0x00000102;
|
||||
WAIT_FAILED :: 0xffffffff;
|
||||
|
||||
CS_VREDRAW :: 0x0001;
|
||||
CS_HREDRAW :: 0x0002;
|
||||
@@ -316,28 +346,44 @@ foreign kernel32 {
|
||||
get_process_heap :: proc() -> Handle #cc_std #link_name "GetProcessHeap" ---;
|
||||
|
||||
|
||||
create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #cc_std #link_name "CreateSemaphoreA" ---;
|
||||
create_semaphore_a :: proc(attributes: ^SecurityAttributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #cc_std #link_name "CreateSemaphoreA" ---;
|
||||
release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #cc_std #link_name "ReleaseSemaphore" ---;
|
||||
wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 #cc_std #link_name "WaitForSingleObject" ---;
|
||||
|
||||
|
||||
interlocked_compare_exchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #cc_std #link_name "InterlockedCompareExchange" ---;
|
||||
interlocked_exchange :: proc(dst: ^i32, desired: i32) -> i32 #cc_std #link_name "InterlockedExchange" ---;
|
||||
interlocked_exchange_add :: proc(dst: ^i32, desired: i32) -> i32 #cc_std #link_name "InterlockedExchangeAdd" ---;
|
||||
interlocked_and :: proc(dst: ^i32, desired: i32) -> i32 #cc_std #link_name "InterlockedAnd" ---;
|
||||
interlocked_or :: proc(dst: ^i32, desired: i32) -> i32 #cc_std #link_name "InterlockedOr" ---;
|
||||
interlocked_compare_exchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #cc_c #link_name "InterlockedCompareExchange" ---;
|
||||
interlocked_exchange :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedExchange" ---;
|
||||
interlocked_exchange_add :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedExchangeAdd" ---;
|
||||
interlocked_and :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedAnd" ---;
|
||||
interlocked_or :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedOr" ---;
|
||||
|
||||
interlocked_compare_exchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64 #cc_std #link_name "InterlockedCompareExchange64" ---;
|
||||
interlocked_exchange64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_std #link_name "InterlockedExchange64" ---;
|
||||
interlocked_exchange_add64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_std #link_name "InterlockedExchangeAdd64" ---;
|
||||
interlocked_and64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_std #link_name "InterlockedAnd64" ---;
|
||||
interlocked_or64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_std #link_name "InterlockedOr64" ---;
|
||||
interlocked_compare_exchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64 #cc_c #link_name "InterlockedCompareExchange64" ---;
|
||||
interlocked_exchange64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedExchange64" ---;
|
||||
interlocked_exchange_add64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedExchangeAdd64" ---;
|
||||
interlocked_and64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedAnd64" ---;
|
||||
interlocked_or64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedOr64" ---;
|
||||
|
||||
mm_pause :: proc() #cc_std #link_name "_mm_pause" ---;
|
||||
read_write_barrier :: proc() #cc_std #link_name "ReadWriteBarrier" ---;
|
||||
write_barrier :: proc() #cc_std #link_name "WriteBarrier" ---;
|
||||
read_barrier :: proc() #cc_std #link_name "ReadBarrier" ---;
|
||||
|
||||
create_thread :: proc(thread_attributes: ^SecurityAttributes, stack_size: int, start_routine: rawptr,
|
||||
parameter: rawptr, creation_flags: u32, thread_id: ^u32) -> Handle #cc_std #link_name "CreateThread" ---;
|
||||
resume_thread :: proc(thread: Handle) -> u32 #cc_std #link_name "ResumeThread" ---;
|
||||
get_thread_priority :: proc(thread: Handle) -> i32 #cc_std #link_name "GetThreadPriority" ---;
|
||||
set_thread_priority :: proc(thread: Handle, priority: i32) -> Bool #cc_std #link_name "SetThreadPriority" ---;
|
||||
get_exit_code_thread :: proc(thread: Handle, exit_code: ^u32) -> Bool #cc_std #link_name "GetExitCodeThread" ---;
|
||||
|
||||
initialize_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "InitializeCriticalSection" ---;
|
||||
initialize_critical_section_and_spin_count :: proc(critical_section: ^CriticalSection, spin_count: u32) #cc_std #link_name "InitializeCriticalSectionAndSpinCount" ---;
|
||||
delete_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "DeleteCriticalSection" ---;
|
||||
set_critical_section_spin_count :: proc(critical_section: ^CriticalSection, spin_count: u32) -> u32 #cc_std #link_name "SetCriticalSectionSpinCount" ---;
|
||||
try_enter_critical_section :: proc(critical_section: ^CriticalSection) -> Bool #cc_std #link_name "TryEnterCriticalSection" ---;
|
||||
enter_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "EnterCriticalSection" ---;
|
||||
leave_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "LeaveCriticalSection" ---;
|
||||
|
||||
create_event_a :: proc(event_attributes: ^SecurityAttributes, manual_reset, initial_state: Bool, name: ^u8) -> Handle #cc_std #link_name "CreateEventA" ---;
|
||||
|
||||
load_library_a :: proc(c_str: ^u8) -> Hmodule #cc_std #link_name "LoadLibraryA" ---;
|
||||
free_library :: proc(h: Hmodule) #cc_std #link_name "FreeLibrary" ---;
|
||||
|
||||
@@ -3992,7 +3992,25 @@ AstNode *parse_for_stmt(AstFile *f) {
|
||||
if (f->curr_token.kind != Token_OpenBrace &&
|
||||
f->curr_token.kind != Token_do) {
|
||||
isize prev_level = f->expr_level;
|
||||
defer (f->expr_level = prev_level);
|
||||
f->expr_level = -1;
|
||||
|
||||
if (f->curr_token.kind == Token_in) {
|
||||
Token in_token = expect_token(f, Token_in);
|
||||
AstNode *rhs = nullptr;
|
||||
bool prev_allow_range = f->allow_range;
|
||||
f->allow_range = true;
|
||||
rhs = parse_expr(f, false);
|
||||
f->allow_range = prev_allow_range;
|
||||
|
||||
if (allow_token(f, Token_do)) {
|
||||
body = convert_stmt_to_body(f, parse_stmt(f));
|
||||
} else {
|
||||
body = parse_block_stmt(f, false);
|
||||
}
|
||||
return ast_range_stmt(f, token, nullptr, nullptr, in_token, rhs, body);
|
||||
}
|
||||
|
||||
if (f->curr_token.kind != Token_Semicolon) {
|
||||
cond = parse_simple_stmt(f, StmtAllowFlag_In);
|
||||
if (cond->kind == AstNode_AssignStmt && cond->AssignStmt.op.kind == Token_in) {
|
||||
@@ -4014,7 +4032,6 @@ AstNode *parse_for_stmt(AstFile *f) {
|
||||
}
|
||||
}
|
||||
|
||||
f->expr_level = prev_level;
|
||||
}
|
||||
|
||||
if (allow_token(f, Token_do)) {
|
||||
|
||||
@@ -94,14 +94,14 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_if, "if"), \
|
||||
TOKEN_KIND(Token_else, "else"), \
|
||||
TOKEN_KIND(Token_for, "for"), \
|
||||
TOKEN_KIND(Token_in, "in"), \
|
||||
TOKEN_KIND(Token_match, "match"), \
|
||||
TOKEN_KIND(Token_in, "in"), \
|
||||
TOKEN_KIND(Token_do, "do"), \
|
||||
TOKEN_KIND(Token_case, "case"), \
|
||||
TOKEN_KIND(Token_break, "break"), \
|
||||
TOKEN_KIND(Token_continue, "continue"), \
|
||||
TOKEN_KIND(Token_fallthrough, "fallthrough"), \
|
||||
TOKEN_KIND(Token_defer, "defer"), \
|
||||
TOKEN_KIND(Token_do, "do"), \
|
||||
TOKEN_KIND(Token_return, "return"), \
|
||||
TOKEN_KIND(Token_proc, "proc"), \
|
||||
TOKEN_KIND(Token_macro, "macro"), \
|
||||
@@ -111,9 +111,9 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_enum, "enum"), \
|
||||
TOKEN_KIND(Token_bit_field, "bit_field"), \
|
||||
TOKEN_KIND(Token_vector, "vector"), \
|
||||
TOKEN_KIND(Token_map, "map"), \
|
||||
TOKEN_KIND(Token_static, "static"), \
|
||||
TOKEN_KIND(Token_dynamic, "dynamic"), \
|
||||
TOKEN_KIND(Token_map, "map"), \
|
||||
TOKEN_KIND(Token_using, "using"), \
|
||||
TOKEN_KIND(Token_context, "context"), \
|
||||
TOKEN_KIND(Token_push_context, "push_context"), \
|
||||
|
||||
Reference in New Issue
Block a user