Parcourir la source

Merge branch 'master' of https://github.com/odin-lang/Odin

gingerBill il y a 6 jours
Parent
commit
b095dd71cb

+ 1 - 1
base/builtin/builtin.odin

@@ -145,7 +145,7 @@ ODIN_OS_STRING                  :: ODIN_OS_STRING
 
 /*
 	An `enum` value indicating the platform subtarget, chosen using the `-subtarget` switch.
-	Possible values are: `.Default` `.iOS`, .iPhoneSimulator, and `.Android`.
+	Possible values are: `.Default` `.iPhone`, .iPhoneSimulator, and `.Android`.
 */
 ODIN_PLATFORM_SUBTARGET         :: ODIN_PLATFORM_SUBTARGET
 

+ 3 - 1
base/runtime/core.odin

@@ -557,7 +557,7 @@ ALL_ODIN_OS_TYPES :: Odin_OS_Types{
 	// Defined internally by the compiler
 	Odin_Platform_Subtarget_Type :: enum int {
 		Default,
-		iOS,
+		iPhone,
 		iPhoneSimulator
 		Android,
 	}
@@ -566,6 +566,8 @@ Odin_Platform_Subtarget_Type :: type_of(ODIN_PLATFORM_SUBTARGET)
 
 Odin_Platform_Subtarget_Types :: bit_set[Odin_Platform_Subtarget_Type]
 
+@(builtin)
+ODIN_PLATFORM_SUBTARGET_IOS :: ODIN_PLATFORM_SUBTARGET == .iPhone || ODIN_PLATFORM_SUBTARGET == .iPhoneSimulator
 
 /*
 	// Defined internally by the compiler

+ 2 - 3
core/crypto/hash/hash.odin

@@ -21,8 +21,7 @@ hash_string :: proc(algorithm: Algorithm, data: string, allocator := context.all
 // in a newly allocated slice.
 hash_bytes :: proc(algorithm: Algorithm, data: []byte, allocator := context.allocator) -> []byte {
 	dst := make([]byte, DIGEST_SIZES[algorithm], allocator)
-	hash_bytes_to_buffer(algorithm, data, dst)
-	return dst
+	return hash_bytes_to_buffer(algorithm, data, dst)
 }
 
 // hash_string_to_buffer will hash the given input and assign the
@@ -46,7 +45,7 @@ hash_bytes_to_buffer :: proc(algorithm: Algorithm, data, hash: []byte) -> []byte
 	update(&ctx, data)
 	final(&ctx, hash)
 
-	return hash
+	return hash[:DIGEST_SIZES[algorithm]]
 }
 
 // hash_stream will incrementally fully consume a stream, and return the

+ 2 - 2
core/os/os_freebsd.odin

@@ -967,8 +967,8 @@ _processor_core_count :: proc() -> int {
 @(private, require_results)
 _alloc_command_line_arguments :: proc() -> []string {
 	res := make([]string, len(runtime.args__))
-	for arg, i in runtime.args__ {
-		res[i] = string(arg)
+	for _, i in res {
+		res[i] = string(runtime.args__[i])
 	}
 	return res
 }

+ 2 - 2
core/os/os_linux.odin

@@ -1100,8 +1100,8 @@ _processor_core_count :: proc() -> int {
 @(private, require_results)
 _alloc_command_line_arguments :: proc() -> []string {
 	res := make([]string, len(runtime.args__))
-	for arg, i in runtime.args__ {
-		res[i] = string(arg)
+	for _, i in  res {
+		res[i] = string(runtime.args__[i])
 	}
 	return res
 }

+ 2 - 2
core/os/os_netbsd.odin

@@ -1017,8 +1017,8 @@ _processor_core_count :: proc() -> int {
 @(private, require_results)
 _alloc_command_line_arguments :: proc() -> []string {
 	res := make([]string, len(runtime.args__))
-	for arg, i in runtime.args__ {
-		res[i] = string(arg)
+	for _, i in res {
+		res[i] = string(runtime.args__[i])
 	}
 	return res
 }

+ 2 - 2
core/os/os_openbsd.odin

@@ -917,8 +917,8 @@ _processor_core_count :: proc() -> int {
 @(private, require_results)
 _alloc_command_line_arguments :: proc() -> []string {
 	res := make([]string, len(runtime.args__))
-	for arg, i in runtime.args__ {
-		res[i] = string(arg)
+	for _, i in res {
+		res[i] = string(runtime.args__[i])
 	}
 	return res
 }

+ 1 - 0
core/path/filepath/match.odin

@@ -1,4 +1,5 @@
 #+build !wasi
+#+build !js
 package filepath
 
 import "core:os"

+ 1 - 0
core/path/filepath/walk.odin

@@ -1,4 +1,5 @@
 #+build !wasi
+#+build !js
 package filepath
 
 import "core:os"

+ 5 - 15
core/sys/darwin/sync.odin

@@ -3,23 +3,13 @@ package darwin
 // #define OS_WAIT_ON_ADDR_AVAILABILITY \
 // 	__API_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
 when ODIN_OS == .Darwin {
-
-	when ODIN_PLATFORM_SUBTARGET == .iOS && ODIN_MINIMUM_OS_VERSION >= 17_04_00 {
-		WAIT_ON_ADDRESS_AVAILABLE :: true
-	} else when ODIN_MINIMUM_OS_VERSION >= 14_04_00 {
-		WAIT_ON_ADDRESS_AVAILABLE :: true
+	when ODIN_PLATFORM_SUBTARGET_IOS {
+		WAIT_ON_ADDRESS_AVAILABLE :: ODIN_MINIMUM_OS_VERSION >= 17_04_00
+		ULOCK_WAIT_2_AVAILABLE    :: ODIN_MINIMUM_OS_VERSION >= 14_00_00
 	} else {
-		WAIT_ON_ADDRESS_AVAILABLE :: false
+		WAIT_ON_ADDRESS_AVAILABLE :: ODIN_MINIMUM_OS_VERSION >= 14_04_00
+		ULOCK_WAIT_2_AVAILABLE    :: ODIN_MINIMUM_OS_VERSION >= 11_00_00
 	}
-
-	when ODIN_PLATFORM_SUBTARGET == .iOS && ODIN_MINIMUM_OS_VERSION >= 14_00_00 {
-		ULOCK_WAIT_2_AVAILABLE :: true
-	} else when ODIN_MINIMUM_OS_VERSION >= 11_00_00 {
-		ULOCK_WAIT_2_AVAILABLE :: true
-	} else {
-		ULOCK_WAIT_2_AVAILABLE :: false
-	}
-
 } else {
 	WAIT_ON_ADDRESS_AVAILABLE :: false
 	ULOCK_WAIT_2_AVAILABLE    :: false

+ 1 - 1
core/sys/info/platform_darwin.odin

@@ -28,7 +28,7 @@ init_platform :: proc() {
 
 	macos_version = {int(version.majorVersion), int(version.minorVersion), int(version.patchVersion)}
 
-	when ODIN_PLATFORM_SUBTARGET == .iOS {
+	when ODIN_PLATFORM_SUBTARGET_IOS {
 		os_version.platform = .iOS
 		ws(&b, "iOS")
 	} else {

+ 3 - 2
core/sys/windows/ole32.odin

@@ -25,11 +25,12 @@ COINIT :: enum DWORD {
 	SPEED_OVER_MEMORY = 0x8,
 }
 
+IUnknown_UUID_STRING :: "00000000-0000-0000-C000-000000000046"
+IUnknown_UUID := &IID{0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
+IUnknownVtbl :: IUnknown_VTable
 IUnknown :: struct {
 	using _iunknown_vtable: ^IUnknown_VTable,
 }
-
-IUnknownVtbl :: IUnknown_VTable
 IUnknown_VTable :: struct {
 	QueryInterface: proc "system" (This: ^IUnknown, riid: REFIID, ppvObject: ^rawptr) -> HRESULT,
 	AddRef:         proc "system" (This: ^IUnknown) -> ULONG,

+ 6 - 6
src/build_settings.cpp

@@ -171,7 +171,7 @@ struct TargetMetrics {
 
 enum Subtarget : u32 {
 	Subtarget_Default,
-	Subtarget_iOS,
+	Subtarget_iPhone,
 	Subtarget_iPhoneSimulator,
 	Subtarget_Android,
 
@@ -180,7 +180,7 @@ enum Subtarget : u32 {
 
 gb_global String subtarget_strings[Subtarget_COUNT] = {
 	str_lit(""),
-	str_lit("ios"),
+	str_lit("iphone"),
 	str_lit("iphonesimulator"),
 	str_lit("android"),
 };
@@ -1828,13 +1828,13 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
 
 	if (metrics->os == TargetOs_darwin) {
 		switch (subtarget) {
-			case Subtarget_iOS:
+			case Subtarget_iPhone:
 				switch (metrics->arch) {
 				case TargetArch_arm64:
 					bc->metrics.target_triplet = str_lit("arm64-apple-ios");
 					break;
 				default:
-					GB_PANIC("Unknown architecture for -subtarget:ios");
+					GB_PANIC("Unknown architecture for -subtarget:iphone");
 				}
 				break;
 			case Subtarget_iPhoneSimulator:
@@ -1909,7 +1909,7 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
 		if (!bc->minimum_os_version_string_given) {
 			if (subtarget == Subtarget_Default) {
 				bc->minimum_os_version_string = str_lit("11.0.0");
-			} else if (subtarget == Subtarget_iOS || subtarget == Subtarget_iPhoneSimulator) {
+			} else if (subtarget == Subtarget_iPhone || subtarget == Subtarget_iPhoneSimulator) {
 				// NOTE(harold): We default to 17.4 on iOS because that's when os_sync_wait_on_address was added and
 				//               we'd like to avoid any potential App Store issues by using the private ulock_* there.
 				bc->minimum_os_version_string = str_lit("17.4");
@@ -1917,7 +1917,7 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
 		}
 
 		if (subtarget == Subtarget_iPhoneSimulator) {
-			// For the iOS simulator subtarget, the version must be between 'ios' and '-simulator'.
+			// For the iPhoneSimulator subtarget, the version must be between 'ios' and '-simulator'.
 			String suffix = str_lit("-simulator");
 			GB_ASSERT(string_ends_with(bc->metrics.target_triplet, suffix));
 

+ 102 - 94
src/check_decl.cpp

@@ -1001,120 +1001,128 @@ gb_internal String handle_link_name(CheckerContext *ctx, Token token, String lin
 
 
 gb_internal void check_objc_methods(CheckerContext *ctx, Entity *e, AttributeContext &ac) {
-	if (!(ac.objc_name.len || ac.objc_is_class_method || ac.objc_type)) {
+	if (!ac.objc_type) {
 		return;
 	}
-	if (ac.objc_name.len == 0 && ac.objc_is_class_method) {
-		error(e->token, "@(objc_name) is required with @(objc_is_class_method)");
-	} else if (ac.objc_type == nullptr) {
-		error(e->token, "@(objc_name) requires that @(objc_type) to be set");
-	} else if (ac.objc_name.len == 0 && ac.objc_type) {
-		error(e->token, "@(objc_name) is required with @(objc_type)");
-	} else {
-		Type *t = ac.objc_type;
 
-		GB_ASSERT(t->kind == Type_Named);	// NOTE(harold): This is already checked for at the attribute resolution stage.
-		Entity *tn = t->Named.type_name;
+	Type *t = ac.objc_type;
+	GB_ASSERT(t->kind == Type_Named);	// NOTE(harold): This is already checked for at the attribute resolution stage.
 
-		GB_ASSERT(tn->kind == Entity_TypeName);
+	// Attempt to infer th objc_name automatically if the proc name contains
+	// the type name objc_type's name, followed by an underscore, as a prefix.
+	if (ac.objc_name.len == 0) {
+		String proc_name = e->token.string;
+		String type_name = t->Named.name;
 
-		if (tn->scope != e->scope) {
-			error(e->token, "@(objc_name) attribute may only be applied to procedures and types within the same scope");
+		if (proc_name.len > type_name.len + 1 &&
+			proc_name[type_name.len] == '_' &&
+			str_eq(type_name, substring(proc_name, 0, type_name.len))
+		) {
+			ac.objc_name = substring(proc_name, type_name.len+1, proc_name.len);
 		} else {
+			error(e->token, "@(objc_name) requires that @(objc_type) be set or inferred "
+							"by prefixing the proc name with the type and underscore: MyObjcType_myProcName :: proc().");
+		}
+	}
 
-			// Enable implementation by default if the class is an implementer too and
-			// @objc_implement was not set to false explicitly in this proc.
-			bool implement = tn->TypeName.objc_is_implementation;
-			if (ac.objc_is_disabled_implement) {
-				implement = false;
-			}
+	Entity *tn = t->Named.type_name;
+	GB_ASSERT(tn->kind == Entity_TypeName);
 
-			if (implement) {
-				GB_ASSERT(e->kind == Entity_Procedure);
-
-				auto &proc = e->type->Proc;
-				Type *first_param = proc.param_count > 0 ? proc.params->Tuple.variables[0]->type : t_untyped_nil;
-
-				if (!tn->TypeName.objc_is_implementation) {
-					error(e->token, "@(objc_is_implement) attribute may only be applied to procedures whose class also have @(objc_is_implement) applied");
-				} else if (!ac.objc_is_class_method && !(first_param->kind == Type_Pointer && internal_check_is_assignable_to(t, first_param->Pointer.elem))) {
-					error(e->token, "Objective-C instance methods implementations require the first parameter to be a pointer to the class type set by @(objc_type)");
-				} else if (proc.calling_convention == ProcCC_Odin && !tn->TypeName.objc_context_provider) {
-					error(e->token, "Objective-C methods with Odin calling convention can only be used with classes that have @(objc_context_provider) set");
-				} else if (ac.objc_is_class_method && proc.calling_convention != ProcCC_CDecl) {
-					error(e->token, "Objective-C class methods (objc_is_class_method=true) that have @objc_is_implementation can only use \"c\" calling convention");
-				} else if (proc.result_count > 1) {
-					error(e->token, "Objective-C method implementations may return at most 1 value");
-				} else {
-					// Always export unconditionally
-					// NOTE(harold): This means check_objc_methods() MUST be called before
-					//				 e->Procedure.is_export is set in check_proc_decl()!
-					if (ac.is_export) {
-						error(e->token, "Explicit export not allowed when @(objc_implement) is set. It set exported implicitly");
-					}
-					if (ac.link_name != "") {
-						error(e->token, "Explicit linkage not allowed when @(objc_implement) is set. It set to \"strong\" implicitly");
-					}
+	if (tn->scope != e->scope) {
+		error(e->token, "@(objc_name) attribute may only be applied to procedures and types within the same scope");
+	} else {
+		// Enable implementation by default if the class is an implementer too and
+		// @objc_implement was not set to false explicitly in this proc.
+		bool implement = tn->TypeName.objc_is_implementation;
+		if (ac.objc_is_disabled_implement) {
+			implement = false;
+		}
+
+		if (implement) {
+			GB_ASSERT(e->kind == Entity_Procedure);
+
+			auto &proc = e->type->Proc;
+			Type *first_param = proc.param_count > 0 ? proc.params->Tuple.variables[0]->type : t_untyped_nil;
+
+			if (!tn->TypeName.objc_is_implementation) {
+				error(e->token, "@(objc_is_implement) attribute may only be applied to procedures whose class also have @(objc_is_implement) applied");
+			} else if (!ac.objc_is_class_method && !(first_param->kind == Type_Pointer && internal_check_is_assignable_to(t, first_param->Pointer.elem))) {
+				error(e->token, "Objective-C instance methods implementations require the first parameter to be a pointer to the class type set by @(objc_type)");
+			} else if (proc.calling_convention == ProcCC_Odin && !tn->TypeName.objc_context_provider) {
+				error(e->token, "Objective-C methods with Odin calling convention can only be used with classes that have @(objc_context_provider) set");
+			} else if (ac.objc_is_class_method && proc.calling_convention != ProcCC_CDecl) {
+				error(e->token, "Objective-C class methods (objc_is_class_method=true) that have @objc_is_implementation can only use \"c\" calling convention");
+			} else if (proc.result_count > 1) {
+				error(e->token, "Objective-C method implementations may return at most 1 value");
+			} else {
+				// Always export unconditionally
+				// NOTE(harold): This means check_objc_methods() MUST be called before
+				//				 e->Procedure.is_export is set in check_proc_decl()!
+				if (ac.is_export) {
+					error(e->token, "Explicit export not allowed when @(objc_implement) is set. It set exported implicitly");
+				}
+				if (ac.link_name != "") {
+					error(e->token, "Explicit linkage not allowed when @(objc_implement) is set. It set to \"strong\" implicitly");
+				}
 
-					ac.is_export = true;
-					ac.linkage   = STR_LIT("strong");
+				ac.is_export = true;
+				ac.linkage   = STR_LIT("strong");
 
-					auto method = ObjcMethodData{ ac, e };
-					method.ac.objc_selector = ac.objc_selector != "" ? ac.objc_selector : ac.objc_name;
+				auto method = ObjcMethodData{ ac, e };
+				method.ac.objc_selector = ac.objc_selector != "" ? ac.objc_selector : ac.objc_name;
 
-					CheckerInfo *info = ctx->info;
-					mutex_lock(&info->objc_method_mutex);
-					defer (mutex_unlock(&info->objc_method_mutex));
+				CheckerInfo *info = ctx->info;
+				mutex_lock(&info->objc_method_mutex);
+				defer (mutex_unlock(&info->objc_method_mutex));
 
-					Array<ObjcMethodData>* method_list = map_get(&info->objc_method_implementations, t);
-					if (method_list) {
-						array_add(method_list, method);
-					} else {
-						auto list = array_make<ObjcMethodData>(permanent_allocator(), 1, 8);
-						list[0] = method;
+				Array<ObjcMethodData>* method_list = map_get(&info->objc_method_implementations, t);
+				if (method_list) {
+					array_add(method_list, method);
+				} else {
+					auto list = array_make<ObjcMethodData>(permanent_allocator(), 1, 8);
+					list[0] = method;
 
-						map_set(&info->objc_method_implementations, t, list);
-					}
+					map_set(&info->objc_method_implementations, t, list);
 				}
-			} else if (ac.objc_selector != "") {
-				error(e->token, "@(objc_selector) may only be applied to procedures that are Objective-C implementations.");
 			}
+		} else if (ac.objc_selector != "") {
+			error(e->token, "@(objc_selector) may only be applied to procedures that are Objective-C implementations.");
+		}
 
-			mutex_lock(&global_type_name_objc_metadata_mutex);
-			defer (mutex_unlock(&global_type_name_objc_metadata_mutex));
+		mutex_lock(&global_type_name_objc_metadata_mutex);
+		defer (mutex_unlock(&global_type_name_objc_metadata_mutex));
 
-			if (!tn->TypeName.objc_metadata) {
-				tn->TypeName.objc_metadata = create_type_name_obj_c_metadata();
-			}
-			auto *md = tn->TypeName.objc_metadata;
-			mutex_lock(md->mutex);
-			defer (mutex_unlock(md->mutex));
-
-			if (!ac.objc_is_class_method) {
-				bool ok = true;
-				for (TypeNameObjCMetadataEntry const &entry : md->value_entries) {
-					if (entry.name == ac.objc_name) {
-						error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name));
-						ok = false;
-						break;
-					}
-				}
-				if (ok) {
-					array_add(&md->value_entries, TypeNameObjCMetadataEntry{ac.objc_name, e});
-				}
-			} else {
-				bool ok = true;
-				for (TypeNameObjCMetadataEntry const &entry : md->type_entries) {
-					if (entry.name == ac.objc_name) {
-						error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name));
-						ok = false;
-						break;
-					}
+		if (!tn->TypeName.objc_metadata) {
+			tn->TypeName.objc_metadata = create_type_name_obj_c_metadata();
+		}
+		auto *md = tn->TypeName.objc_metadata;
+		mutex_lock(md->mutex);
+		defer (mutex_unlock(md->mutex));
+
+		if (!ac.objc_is_class_method) {
+			bool ok = true;
+			for (TypeNameObjCMetadataEntry const &entry : md->value_entries) {
+				if (entry.name == ac.objc_name) {
+					error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name));
+					ok = false;
+					break;
 				}
-				if (ok) {
-					array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_name, e});
+			}
+			if (ok) {
+				array_add(&md->value_entries, TypeNameObjCMetadataEntry{ac.objc_name, e});
+			}
+		} else {
+			bool ok = true;
+			for (TypeNameObjCMetadataEntry const &entry : md->type_entries) {
+				if (entry.name == ac.objc_name) {
+					error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name));
+					ok = false;
+					break;
 				}
 			}
+			if (ok) {
+				array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_name, e});
+			}
 		}
 	}
 }

+ 1 - 1
src/checker.cpp

@@ -1172,7 +1172,7 @@ gb_internal void init_universal(void) {
 	{
 		GlobalEnumValue values[Subtarget_COUNT] = {
 			{"Default",         Subtarget_Default},
-			{"iOS",             Subtarget_iOS},
+			{"iPhone",          Subtarget_iPhone},
 			{"iPhoneSimulator", Subtarget_iPhoneSimulator},
 			{"Android",         Subtarget_Android},
 		};

+ 1 - 1
src/linker.cpp

@@ -787,7 +787,7 @@ try_cross_linking:;
 				//               being set to 'MacOSX' even though we've set the sysroot to the correct SDK (-Wincompatible-sysroot).
 				//               This is because it is likely not using the SDK's toolchain Apple Clang but another one installed in the system.
 				switch (selected_subtarget) {
-				case Subtarget_iOS:
+				case Subtarget_iPhone:
 					darwin_platform_name  = "iPhoneOS";
 					darwin_xcrun_sdk_name = "iphoneos";
 					darwin_min_version_id = "ios";

+ 6 - 6
vendor/sdl3/image/sdl_image.odin

@@ -89,12 +89,12 @@ foreign lib {
 	ReadXPMFromArrayToRGB888 :: proc(xpm: [^]cstring) -> ^SDL.Surface ---
 
 	/* Individual saving functions */
-	SaveAVIF    :: proc(surface: ^SDL.Surface, file: cstring, quality: c.int) -> c.int ---
-	SaveAVIF_IO :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool, quality: c.int) -> c.int ---
-	SavePNG     :: proc(surface: ^SDL.Surface, file: cstring) -> c.int ---
-	SavePNG_IO  :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool) -> c.int ---
-	SaveJPG     :: proc(surface: ^SDL.Surface, file: cstring, quality: c.int) -> c.int ---
-	SaveJPG_IO  :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool, quality: c.int) -> c.int ---
+	SaveAVIF    :: proc(surface: ^SDL.Surface, file: cstring, quality: c.int) -> c.bool ---
+	SaveAVIF_IO :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool, quality: c.int) -> c.bool ---
+	SavePNG     :: proc(surface: ^SDL.Surface, file: cstring) -> c.bool ---
+	SavePNG_IO  :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool) -> c.bool ---
+	SaveJPG     :: proc(surface: ^SDL.Surface, file: cstring, quality: c.int) -> c.bool ---
+	SaveJPG_IO  :: proc(surface: ^SDL.Surface, dst: ^SDL.IOStream, closeio: bool, quality: c.int) -> c.bool ---
 
 	LoadAnimation         :: proc(file: cstring) -> ^Animation ---
 	LoadAnimation_IO      :: proc(src: ^SDL.IOStream, closeio: bool) -> ^Animation ---