Browse Source

Add `wasi_wasm32`

gingerBill 3 years ago
parent
commit
9a5216921c

+ 31 - 31
core/os/os_js_wasm32.odin

@@ -1,70 +1,70 @@
 package os
 package os
 
 
-Handle :: distinct i32;
-Errno :: distinct i32;
+Handle :: distinct i32
+Errno :: distinct i32
 
 
-ERROR_NONE :: Errno(0);
+ERROR_NONE :: Errno(0)
 
 
-O_RDONLY   :: 0x00000;
-O_WRONLY   :: 0x00001;
-O_RDWR     :: 0x00002;
-O_CREATE   :: 0x00040;
-O_EXCL     :: 0x00080;
-O_NOCTTY   :: 0x00100;
-O_TRUNC    :: 0x00200;
-O_NONBLOCK :: 0x00800;
-O_APPEND   :: 0x00400;
-O_SYNC     :: 0x01000;
-O_ASYNC    :: 0x02000;
-O_CLOEXEC  :: 0x80000;
+O_RDONLY   :: 0x00000
+O_WRONLY   :: 0x00001
+O_RDWR     :: 0x00002
+O_CREATE   :: 0x00040
+O_EXCL     :: 0x00080
+O_NOCTTY   :: 0x00100
+O_TRUNC    :: 0x00200
+O_NONBLOCK :: 0x00800
+O_APPEND   :: 0x00400
+O_SYNC     :: 0x01000
+O_ASYNC    :: 0x02000
+O_CLOEXEC  :: 0x80000
 
 
-stdout: Handle;
-stderr: Handle;
-stdin: Handle;
+stdout: Handle
+stderr: Handle
+stdin: Handle
 
 
 
 
 write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
-	return 0, 0;
+	return 0, 0
 }
 }
 read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
-	return 0, 0;
+	return 0, 0
 }
 }
 open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
 open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
-	return 0, 0;
+	return 0, 0
 }
 }
 close :: proc(fd: Handle) -> Errno {
 close :: proc(fd: Handle) -> Errno {
-	return 0;
+	return 0
 }
 }
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
-	return 0, 0;
+	return 0, 0
 }
 }
 current_thread_id :: proc "contextless" () -> int {
 current_thread_id :: proc "contextless" () -> int {
-	return 0;
+	return 0
 }
 }
 
 
 
 
 file_size :: proc(fd: Handle) -> (i64, Errno) {
 file_size :: proc(fd: Handle) -> (i64, Errno) {
-	return 0, 0;
+	return 0, 0
 }
 }
 
 
 
 
 
 
 heap_alloc :: proc(size: int) -> rawptr {
 heap_alloc :: proc(size: int) -> rawptr {
-	return nil;
+	return nil
 }
 }
 heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
 heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
 	if new_size == 0 {
 	if new_size == 0 {
-		heap_free(ptr);
-		return nil;
+		heap_free(ptr)
+		return nil
 	}
 	}
 	if ptr == nil {
 	if ptr == nil {
-		return heap_alloc(new_size);
+		return heap_alloc(new_size)
 	}
 	}
 
 
-	return nil;
+	return nil
 }
 }
 heap_free :: proc(ptr: rawptr) {
 heap_free :: proc(ptr: rawptr) {
 	if ptr == nil {
 	if ptr == nil {
-		return;
+		return
 	}
 	}
 }
 }

+ 1 - 0
core/runtime/default_allocators_general.odin

@@ -1,5 +1,6 @@
 //+build !windows
 //+build !windows
 //+build !freestanding
 //+build !freestanding
+//+build !wasi
 package runtime
 package runtime
 
 
 when ODIN_DEFAULT_TO_NIL_ALLOCATOR {
 when ODIN_DEFAULT_TO_NIL_ALLOCATOR {

+ 89 - 0
core/runtime/internal.odin

@@ -838,3 +838,92 @@ fixunsdfdi :: #force_no_inline proc "c" (a: f64) -> i128 {
 	x := i64(a)
 	x := i64(a)
 	return i128(x)
 	return i128(x)
 }
 }
+
+
+
+
+@(link_name="__umodti3")
+umodti3 :: proc "c" (a, b: u128) -> u128 {
+	r: u128 = ---
+	_ = udivmod128(a, b, &r)
+	return r
+}
+
+
+@(link_name="__udivmodti4")
+udivmodti4 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
+	return udivmod128(a, b, rem)
+}
+
+@(link_name="__udivti3")
+udivti3 :: proc "c" (a, b: u128) -> u128 {
+	return udivmodti4(a, b, nil)
+}
+
+
+@(link_name="__modti3")
+modti3 :: proc "c" (a, b: i128) -> i128 {
+	s_a := a >> (128 - 1)
+	s_b := b >> (128 - 1)
+	an := (a ~ s_a) - s_a
+	bn := (b ~ s_b) - s_b
+
+	r: u128 = ---
+	_ = udivmod128(transmute(u128)an, transmute(u128)bn, &r)
+	return (transmute(i128)r ~ s_a) - s_a
+}
+
+
+@(link_name="__divmodti4")
+divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {
+	u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem)
+	return transmute(i128)u
+}
+
+@(link_name="__divti3")
+divti3 :: proc "c" (a, b: i128) -> i128 {
+	u := udivmodti4(transmute(u128)a, transmute(u128)b, nil)
+	return transmute(i128)u
+}
+
+
+@(link_name="__fixdfti")
+fixdfti :: proc(a: u64) -> i128 {
+	significandBits :: 52
+	typeWidth       :: (size_of(u64)*8)
+	exponentBits    :: (typeWidth - significandBits - 1)
+	maxExponent     :: ((1 << exponentBits) - 1)
+	exponentBias    :: (maxExponent >> 1)
+
+	implicitBit     :: (u64(1) << significandBits)
+	significandMask :: (implicitBit - 1)
+	signBit         :: (u64(1) << (significandBits + exponentBits))
+	absMask         :: (signBit - 1)
+	exponentMask    :: (absMask ~ significandMask)
+
+	// Break a into sign, exponent, significand
+	aRep := a
+	aAbs := aRep & absMask
+	sign := i128(-1 if aRep & signBit != 0 else 1)
+	exponent := u64((aAbs >> significandBits) - exponentBias)
+	significand := u64((aAbs & significandMask) | implicitBit)
+
+	// If exponent is negative, the result is zero.
+	if exponent < 0 {
+		return 0
+	}
+
+	// If the value is too large for the integer type, saturate.
+	if exponent >= size_of(i128) * 8 {
+		return max(i128) if sign == 1 else min(i128)
+	}
+
+	// If 0 <= exponent < significandBits, right shift to get the result.
+	// Otherwise, shift left.
+	if exponent < significandBits {
+		return sign * i128(significand >> (significandBits - exponent))
+	} else {
+		return sign * (i128(significand) << (exponent - significandBits))
+	}
+
+}

+ 0 - 88
core/runtime/internal_linux.odin

@@ -1,89 +1 @@
 package runtime
 package runtime
-
-import "core:intrinsics"
-
-@(link_name="__umodti3")
-umodti3 :: proc "c" (a, b: u128) -> u128 {
-	r: u128 = ---
-	_ = udivmod128(a, b, &r)
-	return r
-}
-
-
-@(link_name="__udivmodti4")
-udivmodti4 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
-	return udivmod128(a, b, rem)
-}
-
-@(link_name="__udivti3")
-udivti3 :: proc "c" (a, b: u128) -> u128 {
-	return udivmodti4(a, b, nil)
-}
-
-
-@(link_name="__modti3")
-modti3 :: proc "c" (a, b: i128) -> i128 {
-	s_a := a >> (128 - 1)
-	s_b := b >> (128 - 1)
-	an := (a ~ s_a) - s_a
-	bn := (b ~ s_b) - s_b
-
-	r: u128 = ---
-	_ = udivmod128(transmute(u128)an, transmute(u128)bn, &r)
-	return (transmute(i128)r ~ s_a) - s_a
-}
-
-
-@(link_name="__divmodti4")
-divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {
-	u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem)
-	return transmute(i128)u
-}
-
-@(link_name="__divti3")
-divti3 :: proc "c" (a, b: i128) -> i128 {
-	u := udivmodti4(transmute(u128)a, transmute(u128)b, nil)
-	return transmute(i128)u
-}
-
-
-@(link_name="__fixdfti")
-fixdfti :: proc(a: u64) -> i128 {
-	significandBits :: 52
-	typeWidth       :: (size_of(u64)*8)
-	exponentBits    :: (typeWidth - significandBits - 1)
-	maxExponent     :: ((1 << exponentBits) - 1)
-	exponentBias    :: (maxExponent >> 1)
-
-	implicitBit     :: (u64(1) << significandBits)
-	significandMask :: (implicitBit - 1)
-	signBit         :: (u64(1) << (significandBits + exponentBits))
-	absMask         :: (signBit - 1)
-	exponentMask    :: (absMask ~ significandMask)
-
-	// Break a into sign, exponent, significand
-	aRep := a
-	aAbs := aRep & absMask
-	sign := i128(-1 if aRep & signBit != 0 else 1)
-	exponent := u64((aAbs >> significandBits) - exponentBias)
-	significand := u64((aAbs & significandMask) | implicitBit)
-
-	// If exponent is negative, the result is zero.
-	if exponent < 0 {
-		return 0
-	}
-
-	// If the value is too large for the integer type, saturate.
-	if exponent >= size_of(i128) * 8 {
-		return max(i128) if sign == 1 else min(i128)
-	}
-
-	// If 0 <= exponent < significandBits, right shift to get the result.
-	// Otherwise, shift left.
-	if exponent < significandBits {
-		return sign * i128(significand >> (significandBits - exponent))
-	} else {
-		return sign * (i128(significand) << (exponent - significandBits))
-	}
-
-}

+ 0 - 88
core/runtime/internal_windows.odin

@@ -1,89 +1 @@
 package runtime
 package runtime
-
-import "core:intrinsics"
-
-@(link_name="__umodti3")
-umodti3 :: proc "c" (a, b: u128) -> u128 {
-	r: u128 = ---
-	_ = udivmod128(a, b, &r)
-	return r
-}
-
-
-@(link_name="__udivmodti4")
-udivmodti4 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
-	return udivmod128(a, b, rem)
-}
-
-@(link_name="__udivti3")
-udivti3 :: proc "c" (a, b: u128) -> u128 {
-	return udivmodti4(a, b, nil)
-}
-
-
-@(link_name="__modti3")
-modti3 :: proc "c" (a, b: i128) -> i128 {
-	s_a := a >> (128 - 1)
-	s_b := b >> (128 - 1)
-	an := (a ~ s_a) - s_a
-	bn := (b ~ s_b) - s_b
-
-	r: u128 = ---
-	_ = udivmod128(transmute(u128)an, transmute(u128)bn, &r)
-	return (transmute(i128)r ~ s_a) - s_a
-}
-
-
-@(link_name="__divmodti4")
-divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {
-	u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem)
-	return transmute(i128)u
-}
-
-@(link_name="__divti3")
-divti3 :: proc "c" (a, b: i128) -> i128 {
-	u := udivmodti4(transmute(u128)a, transmute(u128)b, nil)
-	return transmute(i128)u
-}
-
-
-@(link_name="__fixdfti")
-fixdfti :: proc(a: u64) -> i128 {
-	significandBits :: 52
-	typeWidth       :: (size_of(u64)*8)
-	exponentBits    :: (typeWidth - significandBits - 1)
-	maxExponent     :: ((1 << exponentBits) - 1)
-	exponentBias    :: (maxExponent >> 1)
-
-	implicitBit     :: (u64(1) << significandBits)
-	significandMask :: (implicitBit - 1)
-	signBit         :: (u64(1) << (significandBits + exponentBits))
-	absMask         :: (signBit - 1)
-	exponentMask    :: (absMask ~ significandMask)
-
-	// Break a into sign, exponent, significand
-	aRep := a
-	aAbs := aRep & absMask
-	sign := i128(-1 if aRep & signBit != 0 else 1)
-	exponent := (aAbs >> significandBits) - exponentBias
-	significand := (aAbs & significandMask) | implicitBit
-
-	// If exponent is negative, the result is zero.
-	if exponent < 0 {
-		return 0
-	}
-
-	// If the value is too large for the integer type, saturate.
-	if exponent >= size_of(i128) * 8 {
-		return max(i128) if sign == 1 else min(i128)
-	}
-
-	// If 0 <= exponent < significandBits, right shift to get the result.
-	// Otherwise, shift left.
-	if exponent < significandBits {
-		return sign * i128(significand >> (significandBits - exponent))
-	} else {
-		return sign * (i128(significand) << (exponent - significandBits))
-	}
-
-}

+ 1 - 2
core/runtime/os_specific_any.odin

@@ -1,5 +1,4 @@
-//+build !freestanding
-//+build !windows
+//+build !freestanding !wasi !windows
 package runtime
 package runtime
 
 
 import "core:os"
 import "core:os"

+ 27 - 4
src/build_settings.cpp

@@ -16,6 +16,8 @@ enum TargetOsKind {
 	TargetOs_linux,
 	TargetOs_linux,
 	TargetOs_essence,
 	TargetOs_essence,
 	TargetOs_freebsd,
 	TargetOs_freebsd,
+	
+	TargetOs_wasi,
 
 
 	TargetOs_freestanding,
 	TargetOs_freestanding,
 
 
@@ -50,6 +52,8 @@ String target_os_names[TargetOs_COUNT] = {
 	str_lit("linux"),
 	str_lit("linux"),
 	str_lit("essence"),
 	str_lit("essence"),
 	str_lit("freebsd"),
 	str_lit("freebsd"),
+	
+	str_lit("wasi"),
 
 
 	str_lit("freestanding"),
 	str_lit("freestanding"),
 };
 };
@@ -347,6 +351,16 @@ gb_global TargetMetrics target_freestanding_wasm64 = {
 	str_lit(""),
 	str_lit(""),
 };
 };
 
 
+gb_global TargetMetrics target_wasi_wasm32 = {
+	TargetOs_wasi,
+	TargetArch_wasm32,
+	4,
+	8,
+	str_lit("wasm32-wasi-js"),
+	str_lit(""),
+};
+
+
 
 
 
 
 
 
@@ -367,6 +381,7 @@ gb_global NamedTargetMetrics named_targets[] = {
 	{ str_lit("freebsd_amd64"),  &target_freebsd_amd64  },
 	{ str_lit("freebsd_amd64"),  &target_freebsd_amd64  },
 	{ str_lit("freestanding_wasm32"), &target_freestanding_wasm32 },
 	{ str_lit("freestanding_wasm32"), &target_freestanding_wasm32 },
 	{ str_lit("freestanding_wasm64"), &target_freestanding_wasm64 },
 	{ str_lit("freestanding_wasm64"), &target_freestanding_wasm64 },
+	{ str_lit("wasi_wasm32"), &target_wasi_wasm32 },
 };
 };
 
 
 NamedTargetMetrics *selected_target_metrics;
 NamedTargetMetrics *selected_target_metrics;
@@ -893,10 +908,18 @@ void init_build_context(TargetMetrics *cross_target) {
 			bc->link_flags = str_lit("-arch arm64 ");
 			bc->link_flags = str_lit("-arch arm64 ");
 			break;
 			break;
 		}
 		}
-	} else if (bc->metrics.arch == TargetArch_wasm32) {
-		bc->link_flags = str_lit("--no-entry --export-table --export-all --allow-undefined --features=wasm-feature-atomics ");
-	} else if (bc->metrics.arch == TargetArch_wasm64) {
-		bc->link_flags = str_lit("--no-entry --export-table --export-all --allow-undefined -mwasm64 --features=wasm-feature-memory64,wasm-feature-atomics --verbose ");
+	} else if (is_arch_wasm()) {
+		gbString link_flags = gb_string_make(heap_allocator(), "--export-all  ");
+		link_flags = gb_string_appendc(link_flags, "--export-table ");
+		link_flags = gb_string_appendc(link_flags, "--allow-undefined ");
+		if (bc->metrics.arch == TargetArch_wasm64) {
+			link_flags = gb_string_appendc(link_flags, "-mwas64 ");
+		}
+		if (bc->metrics.os == TargetOs_freestanding) {
+			link_flags = gb_string_appendc(link_flags, "--no-entry ");
+		}
+		
+		bc->link_flags = make_string_c(link_flags);
 	} else {
 	} else {
 		gb_printf_err("Compiler Error: Unsupported architecture\n");
 		gb_printf_err("Compiler Error: Unsupported architecture\n");
 		gb_exit(1);
 		gb_exit(1);

+ 10 - 0
src/llvm_backend.cpp

@@ -784,6 +784,8 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
 		params->Tuple.variables[2] = alloc_entity_param(nullptr, make_token_ident("lpReserved"), t_rawptr, false, true);
 		params->Tuple.variables[2] = alloc_entity_param(nullptr, make_token_ident("lpReserved"), t_rawptr, false, true);
 	} else if (build_context.metrics.os == TargetOs_windows && build_context.metrics.arch == TargetArch_386) {
 	} else if (build_context.metrics.os == TargetOs_windows && build_context.metrics.arch == TargetArch_386) {
 		name = str_lit("mainCRTStartup");
 		name = str_lit("mainCRTStartup");
+	} else if (build_context.metrics.os == TargetOs_wasi) {
+		name = str_lit("_start");
 	} else {
 	} else {
 		has_args = true;
 		has_args = true;
 		slice_init(&params->Tuple.variables, permanent_allocator(), 2);
 		slice_init(&params->Tuple.variables, permanent_allocator(), 2);
@@ -885,6 +887,14 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
 	}
 	}
 
 
 	lb_end_procedure_body(p);
 	lb_end_procedure_body(p);
+	
+	
+	if (build_context.metrics.os == TargetOs_wasi) {
+		LLVMSetLinkage(p->value, LLVMDLLExportLinkage);	
+	} else {
+		LLVMSetLinkage(p->value, LLVMExternalLinkage);
+	}
+	
 
 
 	if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
 	if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
 		gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %s\n", "main");
 		gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %s\n", "main");

+ 4 - 3
src/string.cpp

@@ -21,13 +21,14 @@ struct String {
 };
 };
 // NOTE(bill): used for printf style arguments
 // NOTE(bill): used for printf style arguments
 #define LIT(x) ((int)(x).len), (x).text
 #define LIT(x) ((int)(x).len), (x).text
-#define STR_LIT(c_str) {cast(u8 *)c_str, gb_size_of(c_str)-1}
 #if defined(GB_COMPILER_MSVC) && _MSC_VER < 1700
 #if defined(GB_COMPILER_MSVC) && _MSC_VER < 1700
-	#define str_lit(c_str) make_string(cast(u8 *)c_str, gb_size_of(c_str)-1)
+	#define STR_LIT(c_str) make_string(cast(u8 *)c_str, gb_size_of(c_str)-1)
 #else
 #else
-	#define str_lit(c_str) String{cast(u8 *)c_str, gb_size_of(c_str)-1}
+	#define STR_LIT(c_str) String{cast(u8 *)c_str, gb_size_of(c_str)-1}
 #endif
 #endif
 
 
+#define str_lit(c_str) STR_LIT(c_str)
+
 // NOTE(bill): String16 is only used for Windows due to its file directories
 // NOTE(bill): String16 is only used for Windows due to its file directories
 struct String16 {
 struct String16 {
 	wchar_t *text;
 	wchar_t *text;