mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 16:18:52 +00:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
+14
-8
@@ -26,12 +26,18 @@ when ODIN_NO_CRT && ODIN_OS == .Windows {
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
} else when ODIN_NO_CRT || (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32) {
|
} else when ODIN_NO_CRT || (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32) {
|
||||||
|
// NOTE: on wasm, calls to these procs are generated (by LLVM) with type `i32` instead of `int`.
|
||||||
|
//
|
||||||
|
// NOTE: `#any_int` is also needed, because calls that we generate (and package code)
|
||||||
|
// will be using `int` and need to be converted.
|
||||||
|
int_t :: i32 when ODIN_ARCH == .wasm64p32 else int
|
||||||
|
|
||||||
@(link_name="memset", linkage="strong", require)
|
@(link_name="memset", linkage="strong", require)
|
||||||
memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr {
|
memset :: proc "c" (ptr: rawptr, val: i32, #any_int len: int_t) -> rawptr {
|
||||||
if ptr != nil && len != 0 {
|
if ptr != nil && len != 0 {
|
||||||
b := byte(val)
|
b := byte(val)
|
||||||
p := ([^]byte)(ptr)
|
p := ([^]byte)(ptr)
|
||||||
for i := 0; i < len; i += 1 {
|
for i := int_t(0); i < len; i += 1 {
|
||||||
p[i] = b
|
p[i] = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,10 +45,10 @@ when ODIN_NO_CRT && ODIN_OS == .Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@(link_name="bzero", linkage="strong", require)
|
@(link_name="bzero", linkage="strong", require)
|
||||||
bzero :: proc "c" (ptr: rawptr, len: int) -> rawptr {
|
bzero :: proc "c" (ptr: rawptr, #any_int len: int_t) -> rawptr {
|
||||||
if ptr != nil && len != 0 {
|
if ptr != nil && len != 0 {
|
||||||
p := ([^]byte)(ptr)
|
p := ([^]byte)(ptr)
|
||||||
for i := 0; i < len; i += 1 {
|
for i := int_t(0); i < len; i += 1 {
|
||||||
p[i] = 0
|
p[i] = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +56,7 @@ when ODIN_NO_CRT && ODIN_OS == .Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@(link_name="memmove", linkage="strong", require)
|
@(link_name="memmove", linkage="strong", require)
|
||||||
memmove :: proc "c" (dst, src: rawptr, len: int) -> rawptr {
|
memmove :: proc "c" (dst, src: rawptr, #any_int len: int_t) -> rawptr {
|
||||||
d, s := ([^]byte)(dst), ([^]byte)(src)
|
d, s := ([^]byte)(dst), ([^]byte)(src)
|
||||||
if d == s || len == 0 {
|
if d == s || len == 0 {
|
||||||
return dst
|
return dst
|
||||||
@@ -63,7 +69,7 @@ when ODIN_NO_CRT && ODIN_OS == .Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s > d && uintptr(s)-uintptr(d) < uintptr(len) {
|
if s > d && uintptr(s)-uintptr(d) < uintptr(len) {
|
||||||
for i := 0; i < len; i += 1 {
|
for i := int_t(0); i < len; i += 1 {
|
||||||
d[i] = s[i]
|
d[i] = s[i]
|
||||||
}
|
}
|
||||||
return dst
|
return dst
|
||||||
@@ -71,10 +77,10 @@ when ODIN_NO_CRT && ODIN_OS == .Windows {
|
|||||||
return memcpy(dst, src, len)
|
return memcpy(dst, src, len)
|
||||||
}
|
}
|
||||||
@(link_name="memcpy", linkage="strong", require)
|
@(link_name="memcpy", linkage="strong", require)
|
||||||
memcpy :: proc "c" (dst, src: rawptr, len: int) -> rawptr {
|
memcpy :: proc "c" (dst, src: rawptr, #any_int len: int_t) -> rawptr {
|
||||||
d, s := ([^]byte)(dst), ([^]byte)(src)
|
d, s := ([^]byte)(dst), ([^]byte)(src)
|
||||||
if d != s {
|
if d != s {
|
||||||
for i := 0; i < len; i += 1 {
|
for i := int_t(0); i < len; i += 1 {
|
||||||
d[i] = s[i]
|
d[i] = s[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
package encoding_ini
|
||||||
|
|
||||||
|
import "base:runtime"
|
||||||
|
import "base:intrinsics"
|
||||||
|
import "core:strings"
|
||||||
|
import "core:strconv"
|
||||||
|
import "core:io"
|
||||||
|
import "core:os"
|
||||||
|
import "core:fmt"
|
||||||
|
_ :: fmt
|
||||||
|
|
||||||
|
Options :: struct {
|
||||||
|
comment: string,
|
||||||
|
key_lower_case: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFAULT_OPTIONS :: Options {
|
||||||
|
comment = ";",
|
||||||
|
key_lower_case = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator :: struct {
|
||||||
|
section: string,
|
||||||
|
_src: string,
|
||||||
|
options: Options,
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator_from_string :: proc(src: string, options := DEFAULT_OPTIONS) -> Iterator {
|
||||||
|
return {
|
||||||
|
section = "",
|
||||||
|
options = options,
|
||||||
|
_src = src,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the raw `key` and `value`. `ok` will be false if no more key=value pairs cannot be found.
|
||||||
|
// They key and value may be quoted, which may require the use of `strconv.unquote_string`.
|
||||||
|
iterate :: proc(it: ^Iterator) -> (key, value: string, ok: bool) {
|
||||||
|
for line_ in strings.split_lines_iterator(&it._src) {
|
||||||
|
line := strings.trim_space(line_)
|
||||||
|
|
||||||
|
if len(line) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if line[0] == '[' {
|
||||||
|
end_idx := strings.index_byte(line, ']')
|
||||||
|
if end_idx < 0 {
|
||||||
|
end_idx = len(line)
|
||||||
|
}
|
||||||
|
it.section = line[1:end_idx]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if it.options.comment != "" && strings.has_prefix(line, it.options.comment) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
equal := strings.index(line, " =") // check for things keys that `ctrl+= = zoom_in`
|
||||||
|
quote := strings.index_byte(line, '"')
|
||||||
|
if equal < 0 || quote > 0 && quote < equal {
|
||||||
|
equal = strings.index_byte(line, '=')
|
||||||
|
if equal < 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
equal += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
key = strings.trim_space(line[:equal])
|
||||||
|
value = strings.trim_space(line[equal+1:])
|
||||||
|
ok = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
it.section = ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Map :: distinct map[string]map[string]string
|
||||||
|
|
||||||
|
load_map_from_string :: proc(src: string, allocator: runtime.Allocator, options := DEFAULT_OPTIONS) -> (m: Map, err: runtime.Allocator_Error) {
|
||||||
|
unquote :: proc(val: string) -> (string, runtime.Allocator_Error) {
|
||||||
|
v, allocated, ok := strconv.unquote_string(val)
|
||||||
|
if !ok {
|
||||||
|
return strings.clone(val)
|
||||||
|
}
|
||||||
|
if allocated {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
return strings.clone(v)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
context.allocator = allocator
|
||||||
|
|
||||||
|
it := iterator_from_string(src, options)
|
||||||
|
|
||||||
|
for key, value in iterate(&it) {
|
||||||
|
section := it.section
|
||||||
|
if section not_in m {
|
||||||
|
section = strings.clone(section) or_return
|
||||||
|
m[section] = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// store key-value pair
|
||||||
|
pairs := &m[section]
|
||||||
|
new_key := unquote(key) or_return
|
||||||
|
if options.key_lower_case {
|
||||||
|
old_key := new_key
|
||||||
|
new_key = strings.to_lower(key) or_return
|
||||||
|
delete(old_key) or_return
|
||||||
|
}
|
||||||
|
pairs[new_key] = unquote(value) or_return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
load_map_from_path :: proc(path: string, allocator: runtime.Allocator, options := DEFAULT_OPTIONS) -> (m: Map, err: runtime.Allocator_Error, ok: bool) {
|
||||||
|
data := os.read_entire_file(path, allocator) or_return
|
||||||
|
defer delete(data, allocator)
|
||||||
|
m, err = load_map_from_string(string(data), allocator, options)
|
||||||
|
ok = err != nil
|
||||||
|
defer if !ok {
|
||||||
|
delete_map(m)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
save_map_to_string :: proc(m: Map, allocator: runtime.Allocator) -> (data: string) {
|
||||||
|
b := strings.builder_make(allocator)
|
||||||
|
_, _ = write_map(strings.to_writer(&b), m)
|
||||||
|
return strings.to_string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_map :: proc(m: Map) {
|
||||||
|
allocator := m.allocator
|
||||||
|
for section, pairs in m {
|
||||||
|
for key, value in pairs {
|
||||||
|
delete(key, allocator)
|
||||||
|
delete(value, allocator)
|
||||||
|
}
|
||||||
|
delete(section)
|
||||||
|
}
|
||||||
|
delete(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
write_section :: proc(w: io.Writer, name: string, n_written: ^int = nil) -> (n: int, err: io.Error) {
|
||||||
|
defer if n_written != nil { n_written^ += n }
|
||||||
|
io.write_byte (w, '[', &n) or_return
|
||||||
|
io.write_string(w, name, &n) or_return
|
||||||
|
io.write_byte (w, ']', &n) or_return
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
write_pair :: proc(w: io.Writer, key: string, value: $T, n_written: ^int = nil) -> (n: int, err: io.Error) {
|
||||||
|
defer if n_written != nil { n_written^ += n }
|
||||||
|
io.write_string(w, key, &n) or_return
|
||||||
|
io.write_string(w, " = ", &n) or_return
|
||||||
|
when intrinsics.type_is_string(T) {
|
||||||
|
val := string(value)
|
||||||
|
if len(val) > 0 && (val[0] == ' ' || val[len(val)-1] == ' ') {
|
||||||
|
io.write_quoted_string(w, val, n_written=&n) or_return
|
||||||
|
} else {
|
||||||
|
io.write_string(w, val, &n) or_return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
n += fmt.wprint(w, value)
|
||||||
|
}
|
||||||
|
io.write_byte(w, '\n', &n) or_return
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
write_map :: proc(w: io.Writer, m: Map) -> (n: int, err: io.Error) {
|
||||||
|
section_index := 0
|
||||||
|
for section, pairs in m {
|
||||||
|
if section_index == 0 && section == "" {
|
||||||
|
// ignore section
|
||||||
|
} else {
|
||||||
|
write_section(w, section, &n) or_return
|
||||||
|
}
|
||||||
|
for key, value in pairs {
|
||||||
|
write_pair(w, key, value, &n) or_return
|
||||||
|
}
|
||||||
|
section_index += 1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -487,6 +487,7 @@ connect :: proc "contextless" (sock: Fd, addr: ^$T) -> (Errno)
|
|||||||
where
|
where
|
||||||
T == Sock_Addr_In ||
|
T == Sock_Addr_In ||
|
||||||
T == Sock_Addr_In6 ||
|
T == Sock_Addr_In6 ||
|
||||||
|
T == Sock_Addr_Un ||
|
||||||
T == Sock_Addr_Any
|
T == Sock_Addr_Any
|
||||||
{
|
{
|
||||||
ret := syscall(SYS_connect, sock, addr, size_of(T))
|
ret := syscall(SYS_connect, sock, addr, size_of(T))
|
||||||
@@ -502,6 +503,7 @@ accept :: proc "contextless" (sock: Fd, addr: ^$T, sockflags: Socket_FD_Flags =
|
|||||||
where
|
where
|
||||||
T == Sock_Addr_In ||
|
T == Sock_Addr_In ||
|
||||||
T == Sock_Addr_In6 ||
|
T == Sock_Addr_In6 ||
|
||||||
|
T == Sock_Addr_Un ||
|
||||||
T == Sock_Addr_Any
|
T == Sock_Addr_Any
|
||||||
{
|
{
|
||||||
addr_len: i32 = size_of(T)
|
addr_len: i32 = size_of(T)
|
||||||
@@ -514,6 +516,7 @@ recvfrom :: proc "contextless" (sock: Fd, buf: []u8, flags: Socket_Msg, addr: ^$
|
|||||||
where
|
where
|
||||||
T == Sock_Addr_In ||
|
T == Sock_Addr_In ||
|
||||||
T == Sock_Addr_In6 ||
|
T == Sock_Addr_In6 ||
|
||||||
|
T == Sock_Addr_Un ||
|
||||||
T == Sock_Addr_Any
|
T == Sock_Addr_Any
|
||||||
{
|
{
|
||||||
addr_len: i32 = size_of(T)
|
addr_len: i32 = size_of(T)
|
||||||
@@ -531,6 +534,7 @@ sendto :: proc "contextless" (sock: Fd, buf: []u8, flags: Socket_Msg, addr: ^$T)
|
|||||||
where
|
where
|
||||||
T == Sock_Addr_In ||
|
T == Sock_Addr_In ||
|
||||||
T == Sock_Addr_In6 ||
|
T == Sock_Addr_In6 ||
|
||||||
|
T == Sock_Addr_Un ||
|
||||||
T == Sock_Addr_Any
|
T == Sock_Addr_Any
|
||||||
{
|
{
|
||||||
ret := syscall(SYS_sendto, sock, raw_data(buf), len(buf), transmute(i32) flags, addr, size_of(T))
|
ret := syscall(SYS_sendto, sock, raw_data(buf), len(buf), transmute(i32) flags, addr, size_of(T))
|
||||||
@@ -590,6 +594,7 @@ bind :: proc "contextless" (sock: Fd, addr: ^$T) -> (Errno)
|
|||||||
where
|
where
|
||||||
T == Sock_Addr_In ||
|
T == Sock_Addr_In ||
|
||||||
T == Sock_Addr_In6 ||
|
T == Sock_Addr_In6 ||
|
||||||
|
T == Sock_Addr_Un ||
|
||||||
T == Sock_Addr_Any
|
T == Sock_Addr_Any
|
||||||
{
|
{
|
||||||
ret := syscall(SYS_bind, sock, addr, size_of(T))
|
ret := syscall(SYS_bind, sock, addr, size_of(T))
|
||||||
|
|||||||
@@ -631,6 +631,14 @@ Sock_Addr_In6 :: struct #packed {
|
|||||||
sin6_scope_id: u32,
|
sin6_scope_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Struct representing Unix Domain Socket address
|
||||||
|
*/
|
||||||
|
Sock_Addr_Un :: struct #packed {
|
||||||
|
sun_family: Address_Family,
|
||||||
|
sun_path: [108]u8,
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Struct representing an arbitrary socket address.
|
Struct representing an arbitrary socket address.
|
||||||
*/
|
*/
|
||||||
@@ -641,6 +649,7 @@ Sock_Addr_Any :: struct #raw_union {
|
|||||||
},
|
},
|
||||||
using ipv4: Sock_Addr_In,
|
using ipv4: Sock_Addr_In,
|
||||||
using ipv6: Sock_Addr_In6,
|
using ipv6: Sock_Addr_In6,
|
||||||
|
using uds: Sock_Addr_Un,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+13
-1
@@ -23,6 +23,7 @@ enum TargetOsKind : u16 {
|
|||||||
|
|
||||||
TargetOs_wasi,
|
TargetOs_wasi,
|
||||||
TargetOs_js,
|
TargetOs_js,
|
||||||
|
TargetOs_orca,
|
||||||
|
|
||||||
TargetOs_freestanding,
|
TargetOs_freestanding,
|
||||||
|
|
||||||
@@ -90,6 +91,7 @@ gb_global String target_os_names[TargetOs_COUNT] = {
|
|||||||
|
|
||||||
str_lit("wasi"),
|
str_lit("wasi"),
|
||||||
str_lit("js"),
|
str_lit("js"),
|
||||||
|
str_lit("orca"),
|
||||||
|
|
||||||
str_lit("freestanding"),
|
str_lit("freestanding"),
|
||||||
};
|
};
|
||||||
@@ -1067,6 +1069,15 @@ gb_global TargetMetrics target_wasi_wasm32 = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
gb_global TargetMetrics target_orca_wasm32 = {
|
||||||
|
TargetOs_orca,
|
||||||
|
TargetArch_wasm32,
|
||||||
|
4, 4, 8, 16,
|
||||||
|
str_lit("wasm32-wasi-js"),
|
||||||
|
// str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
gb_global TargetMetrics target_freestanding_wasm64p32 = {
|
gb_global TargetMetrics target_freestanding_wasm64p32 = {
|
||||||
TargetOs_freestanding,
|
TargetOs_freestanding,
|
||||||
TargetArch_wasm64p32,
|
TargetArch_wasm64p32,
|
||||||
@@ -2012,8 +2023,9 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
|||||||
// if (bc->metrics.arch == TargetArch_wasm64) {
|
// if (bc->metrics.arch == TargetArch_wasm64) {
|
||||||
// link_flags = gb_string_appendc(link_flags, "-mwasm64 ");
|
// link_flags = gb_string_appendc(link_flags, "-mwasm64 ");
|
||||||
// }
|
// }
|
||||||
if (bc->no_entry_point) {
|
if (bc->no_entry_point || bc->metrics.os == TargetOs_orca) {
|
||||||
link_flags = gb_string_appendc(link_flags, "--no-entry ");
|
link_flags = gb_string_appendc(link_flags, "--no-entry ");
|
||||||
|
bc->no_entry_point = true; // just in case for the "orca" target
|
||||||
}
|
}
|
||||||
|
|
||||||
bc->link_flags = make_string_c(link_flags);
|
bc->link_flags = make_string_c(link_flags);
|
||||||
|
|||||||
+26
-6
@@ -724,9 +724,10 @@ gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) {
|
gb_internal String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix, String link_suffix) {
|
||||||
|
String original_link_name = link_name;
|
||||||
if (link_prefix.len > 0) {
|
if (link_prefix.len > 0) {
|
||||||
if (link_name.len > 0) {
|
if (original_link_name.len > 0) {
|
||||||
error(token, "'link_name' and 'link_prefix' cannot be used together");
|
error(token, "'link_name' and 'link_prefix' cannot be used together");
|
||||||
} else {
|
} else {
|
||||||
isize len = link_prefix.len + token.string.len;
|
isize len = link_prefix.len + token.string.len;
|
||||||
@@ -738,9 +739,28 @@ gb_internal String handle_link_name(CheckerContext *ctx, Token token, String lin
|
|||||||
link_name = make_string(name, len);
|
link_name = make_string(name, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link_suffix.len > 0) {
|
||||||
|
if (original_link_name.len > 0) {
|
||||||
|
error(token, "'link_name' and 'link_suffix' cannot be used together");
|
||||||
|
} else {
|
||||||
|
String new_name = token.string;
|
||||||
|
if (link_name != original_link_name) {
|
||||||
|
new_name = link_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
isize len = new_name.len + link_suffix.len;
|
||||||
|
u8 *name = gb_alloc_array(permanent_allocator(), u8, len+1);
|
||||||
|
gb_memmove(name, &new_name[0], new_name.len);
|
||||||
|
gb_memmove(name+new_name.len, &link_suffix[0], link_suffix.len);
|
||||||
|
name[len] = 0;
|
||||||
|
link_name = make_string(name, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
return link_name;
|
return link_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal void check_objc_methods(CheckerContext *ctx, Entity *e, AttributeContext const &ac) {
|
gb_internal void check_objc_methods(CheckerContext *ctx, Entity *e, AttributeContext const &ac) {
|
||||||
if (!(ac.objc_name.len || ac.objc_is_class_method || ac.objc_type)) {
|
if (!(ac.objc_name.len || ac.objc_is_class_method || ac.objc_type)) {
|
||||||
return;
|
return;
|
||||||
@@ -862,7 +882,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TypeProc *pt = &proc_type->Proc;
|
TypeProc *pt = &proc_type->Proc;
|
||||||
AttributeContext ac = make_attribute_context(e->Procedure.link_prefix);
|
AttributeContext ac = make_attribute_context(e->Procedure.link_prefix, e->Procedure.link_suffix);
|
||||||
|
|
||||||
if (d != nullptr) {
|
if (d != nullptr) {
|
||||||
check_decl_attributes(ctx, d->attributes, proc_decl_attribute, &ac);
|
check_decl_attributes(ctx, d->attributes, proc_decl_attribute, &ac);
|
||||||
@@ -1015,7 +1035,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
|||||||
|
|
||||||
e->deprecated_message = ac.deprecated_message;
|
e->deprecated_message = ac.deprecated_message;
|
||||||
e->warning_message = ac.warning_message;
|
e->warning_message = ac.warning_message;
|
||||||
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
|
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix,ac.link_suffix);
|
||||||
if (ac.has_disabled_proc) {
|
if (ac.has_disabled_proc) {
|
||||||
if (ac.disabled_proc) {
|
if (ac.disabled_proc) {
|
||||||
e->flags |= EntityFlag_Disabled;
|
e->flags |= EntityFlag_Disabled;
|
||||||
@@ -1223,7 +1243,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast
|
|||||||
}
|
}
|
||||||
e->flags |= EntityFlag_Visited;
|
e->flags |= EntityFlag_Visited;
|
||||||
|
|
||||||
AttributeContext ac = make_attribute_context(e->Variable.link_prefix);
|
AttributeContext ac = make_attribute_context(e->Variable.link_prefix, e->Variable.link_suffix);
|
||||||
ac.init_expr_list_count = init_expr != nullptr ? 1 : 0;
|
ac.init_expr_list_count = init_expr != nullptr ? 1 : 0;
|
||||||
|
|
||||||
DeclInfo *decl = decl_info_of_entity(e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
@@ -1244,7 +1264,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast
|
|||||||
if (ac.is_static) {
|
if (ac.is_static) {
|
||||||
error(e->token, "@(static) is not supported for global variables, nor required");
|
error(e->token, "@(static) is not supported for global variables, nor required");
|
||||||
}
|
}
|
||||||
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
|
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix, ac.link_suffix);
|
||||||
|
|
||||||
if (is_arch_wasm() && e->Variable.thread_local_model.len != 0) {
|
if (is_arch_wasm() && e->Variable.thread_local_model.len != 0) {
|
||||||
e->Variable.thread_local_model.len = 0;
|
e->Variable.thread_local_model.len = 0;
|
||||||
|
|||||||
+2
-2
@@ -2020,7 +2020,7 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f
|
|||||||
|
|
||||||
|
|
||||||
// TODO NOTE(bill): This technically checks things multple times
|
// TODO NOTE(bill): This technically checks things multple times
|
||||||
AttributeContext ac = make_attribute_context(ctx->foreign_context.link_prefix);
|
AttributeContext ac = make_attribute_context(ctx->foreign_context.link_prefix, ctx->foreign_context.link_suffix);
|
||||||
check_decl_attributes(ctx, vd->attributes, var_decl_attribute, &ac);
|
check_decl_attributes(ctx, vd->attributes, var_decl_attribute, &ac);
|
||||||
|
|
||||||
for (isize i = 0; i < entity_count; i++) {
|
for (isize i = 0; i < entity_count; i++) {
|
||||||
@@ -2037,7 +2037,7 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f
|
|||||||
e->type = init_type;
|
e->type = init_type;
|
||||||
e->state = EntityState_Resolved;
|
e->state = EntityState_Resolved;
|
||||||
}
|
}
|
||||||
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
|
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix, ac.link_suffix);
|
||||||
|
|
||||||
if (ac.link_name.len > 0) {
|
if (ac.link_name.len > 0) {
|
||||||
e->Variable.link_name = ac.link_name;
|
e->Variable.link_name = ac.link_name;
|
||||||
|
|||||||
@@ -1016,6 +1016,7 @@ gb_internal void init_universal(void) {
|
|||||||
{"NetBSD", TargetOs_netbsd},
|
{"NetBSD", TargetOs_netbsd},
|
||||||
{"WASI", TargetOs_wasi},
|
{"WASI", TargetOs_wasi},
|
||||||
{"JS", TargetOs_js},
|
{"JS", TargetOs_js},
|
||||||
|
{"Orca", TargetOs_orca},
|
||||||
{"Freestanding", TargetOs_freestanding},
|
{"Freestanding", TargetOs_freestanding},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3127,6 +3128,18 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
|||||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (name == "link_suffix") {
|
||||||
|
if (ev.kind == ExactValue_String) {
|
||||||
|
String link_suffix = ev.value_string;
|
||||||
|
if (!is_foreign_name_valid(link_suffix)) {
|
||||||
|
error(elem, "Invalid link suffix: '%.*s'", LIT(link_suffix));
|
||||||
|
} else {
|
||||||
|
c->foreign_context.link_suffix = link_suffix;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
} else if (name == "private") {
|
} else if (name == "private") {
|
||||||
EntityVisiblityKind kind = EntityVisiblity_PrivateToPackage;
|
EntityVisiblityKind kind = EntityVisiblity_PrivateToPackage;
|
||||||
if (ev.kind == ExactValue_Invalid) {
|
if (ev.kind == ExactValue_Invalid) {
|
||||||
@@ -3421,6 +3434,18 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
|||||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (name == "link_suffix") {
|
||||||
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
|
|
||||||
|
if (ev.kind == ExactValue_String) {
|
||||||
|
ac->link_suffix = ev.value_string;
|
||||||
|
if (!is_foreign_name_valid(ac->link_suffix)) {
|
||||||
|
error(elem, "Invalid link suffix: %.*s", LIT(ac->link_suffix));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
} else if (name == "deprecated") {
|
} else if (name == "deprecated") {
|
||||||
ExactValue ev = check_decl_attribute_value(c, value);
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
|
|
||||||
@@ -3702,6 +3727,17 @@ gb_internal DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
|||||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (name == "link_suffix") {
|
||||||
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
|
if (ev.kind == ExactValue_String) {
|
||||||
|
ac->link_suffix = ev.value_string;
|
||||||
|
if (!is_foreign_name_valid(ac->link_suffix)) {
|
||||||
|
error(elem, "Invalid link suffix: %.*s", LIT(ac->link_suffix));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
} else if (name == "link_section") {
|
} else if (name == "link_section") {
|
||||||
ExactValue ev = check_decl_attribute_value(c, value);
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
if (ev.kind == ExactValue_String) {
|
if (ev.kind == ExactValue_String) {
|
||||||
@@ -3733,6 +3769,7 @@ gb_internal DECL_ATTRIBUTE_PROC(const_decl_attribute) {
|
|||||||
name == "linkage" ||
|
name == "linkage" ||
|
||||||
name == "link_name" ||
|
name == "link_name" ||
|
||||||
name == "link_prefix" ||
|
name == "link_prefix" ||
|
||||||
|
name == "link_suffix" ||
|
||||||
false) {
|
false) {
|
||||||
error(elem, "@(%.*s) is not supported for compile time constant value declarations", LIT(name));
|
error(elem, "@(%.*s) is not supported for compile time constant value declarations", LIT(name));
|
||||||
return true;
|
return true;
|
||||||
@@ -3775,8 +3812,10 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array<Ast *> const &at
|
|||||||
if (attributes.count == 0) return;
|
if (attributes.count == 0) return;
|
||||||
|
|
||||||
String original_link_prefix = {};
|
String original_link_prefix = {};
|
||||||
|
String original_link_suffix = {};
|
||||||
if (ac) {
|
if (ac) {
|
||||||
original_link_prefix = ac->link_prefix;
|
original_link_prefix = ac->link_prefix;
|
||||||
|
original_link_suffix = ac->link_suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringSet set = {};
|
StringSet set = {};
|
||||||
@@ -3851,6 +3890,12 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array<Ast *> const &at
|
|||||||
ac->link_prefix.len = 0;
|
ac->link_prefix.len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ac->link_suffix.text == original_link_suffix.text) {
|
||||||
|
if (ac->link_name.len > 0) {
|
||||||
|
ac->link_suffix.text = nullptr;
|
||||||
|
ac->link_suffix.len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4145,6 +4190,7 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
|||||||
e->Variable.foreign_library_ident = fl;
|
e->Variable.foreign_library_ident = fl;
|
||||||
|
|
||||||
e->Variable.link_prefix = c->foreign_context.link_prefix;
|
e->Variable.link_prefix = c->foreign_context.link_prefix;
|
||||||
|
e->Variable.link_suffix = c->foreign_context.link_suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast *init_expr = value;
|
Ast *init_expr = value;
|
||||||
@@ -4219,6 +4265,7 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
e->Procedure.link_prefix = c->foreign_context.link_prefix;
|
e->Procedure.link_prefix = c->foreign_context.link_prefix;
|
||||||
|
e->Procedure.link_suffix = c->foreign_context.link_suffix;
|
||||||
|
|
||||||
GB_ASSERT(cc != ProcCC_Invalid);
|
GB_ASSERT(cc != ProcCC_Invalid);
|
||||||
pl->type->ProcType.calling_convention = cc;
|
pl->type->ProcType.calling_convention = cc;
|
||||||
|
|||||||
+4
-1
@@ -112,6 +112,7 @@ enum InstrumentationFlag : i32 {
|
|||||||
struct AttributeContext {
|
struct AttributeContext {
|
||||||
String link_name;
|
String link_name;
|
||||||
String link_prefix;
|
String link_prefix;
|
||||||
|
String link_suffix;
|
||||||
String link_section;
|
String link_section;
|
||||||
String linkage;
|
String linkage;
|
||||||
isize init_expr_list_count;
|
isize init_expr_list_count;
|
||||||
@@ -146,9 +147,10 @@ struct AttributeContext {
|
|||||||
String enable_target_feature; // will be enabled for the procedure only
|
String enable_target_feature; // will be enabled for the procedure only
|
||||||
};
|
};
|
||||||
|
|
||||||
gb_internal gb_inline AttributeContext make_attribute_context(String link_prefix) {
|
gb_internal gb_inline AttributeContext make_attribute_context(String link_prefix, String link_suffix) {
|
||||||
AttributeContext ac = {};
|
AttributeContext ac = {};
|
||||||
ac.link_prefix = link_prefix;
|
ac.link_prefix = link_prefix;
|
||||||
|
ac.link_suffix = link_suffix;
|
||||||
return ac;
|
return ac;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,6 +304,7 @@ struct ForeignContext {
|
|||||||
Ast * curr_library;
|
Ast * curr_library;
|
||||||
ProcCallingConvention default_cc;
|
ProcCallingConvention default_cc;
|
||||||
String link_prefix;
|
String link_prefix;
|
||||||
|
String link_suffix;
|
||||||
EntityVisiblityKind visibility_kind;
|
EntityVisiblityKind visibility_kind;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ struct Entity {
|
|||||||
Ast * foreign_library_ident;
|
Ast * foreign_library_ident;
|
||||||
String link_name;
|
String link_name;
|
||||||
String link_prefix;
|
String link_prefix;
|
||||||
|
String link_suffix;
|
||||||
String link_section;
|
String link_section;
|
||||||
CommentGroup *docs;
|
CommentGroup *docs;
|
||||||
CommentGroup *comment;
|
CommentGroup *comment;
|
||||||
@@ -243,6 +244,7 @@ struct Entity {
|
|||||||
Ast * foreign_library_ident;
|
Ast * foreign_library_ident;
|
||||||
String link_name;
|
String link_name;
|
||||||
String link_prefix;
|
String link_prefix;
|
||||||
|
String link_suffix;
|
||||||
DeferredProcedure deferred_procedure;
|
DeferredProcedure deferred_procedure;
|
||||||
|
|
||||||
struct GenProcsData *gen_procs;
|
struct GenProcsData *gen_procs;
|
||||||
|
|||||||
+16
-4
@@ -69,15 +69,27 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
|||||||
if (is_arch_wasm()) {
|
if (is_arch_wasm()) {
|
||||||
timings_start_section(timings, str_lit("wasm-ld"));
|
timings_start_section(timings, str_lit("wasm-ld"));
|
||||||
|
|
||||||
|
String extra_orca_flags = {};
|
||||||
|
|
||||||
#if defined(GB_SYSTEM_WINDOWS)
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
|
if (build_context.metrics.os == TargetOs_orca) {
|
||||||
|
extra_orca_flags = str_lit(" W:/orca/installation/dev-afb9591/bin/liborca_wasm.a --export-dynamic");
|
||||||
|
}
|
||||||
|
|
||||||
result = system_exec_command_line_app("wasm-ld",
|
result = system_exec_command_line_app("wasm-ld",
|
||||||
"\"%.*s\\bin\\wasm-ld\" \"%.*s.o\" -o \"%.*s\" %.*s %.*s",
|
"\"%.*s\\bin\\wasm-ld\" \"%.*s.o\" -o \"%.*s\" %.*s %.*s %.*s",
|
||||||
LIT(build_context.ODIN_ROOT),
|
LIT(build_context.ODIN_ROOT),
|
||||||
LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags));
|
LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags),
|
||||||
|
LIT(extra_orca_flags));
|
||||||
#else
|
#else
|
||||||
|
if (build_context.metrics.os == TargetOs_orca) {
|
||||||
|
extra_orca_flags = str_lit(" -L . -lorca --export-dynamic");
|
||||||
|
}
|
||||||
|
|
||||||
result = system_exec_command_line_app("wasm-ld",
|
result = system_exec_command_line_app("wasm-ld",
|
||||||
"wasm-ld \"%.*s.o\" -o \"%.*s\" %.*s %.*s",
|
"wasm-ld \"%.*s.o\" -o \"%.*s\" %.*s %.*s %.*s",
|
||||||
LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags));
|
LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags),
|
||||||
|
LIT(extra_orca_flags));
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1365,6 +1365,8 @@ gb_internal lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection
|
|||||||
} else {
|
} else {
|
||||||
e = lb_emit_ptr_offset(p, lb_emit_load(p, arr), index);
|
e = lb_emit_ptr_offset(p, lb_emit_load(p, arr), index);
|
||||||
}
|
}
|
||||||
|
e.type = alloc_type_multi_pointer_to_pointer(e.type);
|
||||||
|
|
||||||
} else if (is_type_quaternion(type)) {
|
} else if (is_type_quaternion(type)) {
|
||||||
e = lb_emit_struct_ep(p, e, index);
|
e = lb_emit_struct_ep(p, e, index);
|
||||||
} else if (is_type_raw_union(type)) {
|
} else if (is_type_raw_union(type)) {
|
||||||
|
|||||||
+4
-4
@@ -4949,12 +4949,12 @@ CommandQueue_commandBuffer :: #force_inline proc "c" (self: ^CommandQueue) -> ^C
|
|||||||
return msgSend(^CommandBuffer, self, "commandBuffer")
|
return msgSend(^CommandBuffer, self, "commandBuffer")
|
||||||
}
|
}
|
||||||
@(objc_type=CommandQueue, objc_name="commandBufferWithDescriptor")
|
@(objc_type=CommandQueue, objc_name="commandBufferWithDescriptor")
|
||||||
CommandQueue_commandBufferWithDescriptor :: #force_inline proc "c" (self: ^CommandQueue, descriptor: ^CommandBufferDescriptor) -> ^CommandQueue {
|
CommandQueue_commandBufferWithDescriptor :: #force_inline proc "c" (self: ^CommandQueue, descriptor: ^CommandBufferDescriptor) -> ^CommandBuffer {
|
||||||
return msgSend(^CommandQueue, self, "commandBufferWithDescriptor:", descriptor)
|
return msgSend(^CommandBuffer, self, "commandBufferWithDescriptor:", descriptor)
|
||||||
}
|
}
|
||||||
@(objc_type=CommandQueue, objc_name="commandBufferWithUnretainedReferences")
|
@(objc_type=CommandQueue, objc_name="commandBufferWithUnretainedReferences")
|
||||||
CommandQueue_commandBufferWithUnretainedReferences :: #force_inline proc "c" (self: ^CommandQueue) -> ^CommandQueue {
|
CommandQueue_commandBufferWithUnretainedReferences :: #force_inline proc "c" (self: ^CommandQueue) -> ^CommandBuffer {
|
||||||
return msgSend(^CommandQueue, self, "commandBufferWithUnretainedReferences")
|
return msgSend(^CommandBuffer, self, "commandBufferWithUnretainedReferences")
|
||||||
}
|
}
|
||||||
@(objc_type=CommandQueue, objc_name="device")
|
@(objc_type=CommandQueue, objc_name="device")
|
||||||
CommandQueue_device :: #force_inline proc "c" (self: ^CommandQueue) -> ^Device {
|
CommandQueue_device :: #force_inline proc "c" (self: ^CommandQueue) -> ^Device {
|
||||||
|
|||||||
Reference in New Issue
Block a user