Browse Source

Begin work in semi-standardized `js_wasm32` target

gingerBill 3 years ago
parent
commit
518460af66

+ 44 - 0
core/fmt/fmt_js.odin

@@ -0,0 +1,44 @@
+//+build js
+package fmt
+
+import "core:io"
+
+foreign import "odin_env"
+
+@(private="file")
+foreign odin_env {
+	write :: proc "c" (fd: u32, p: []byte) ---
+}
+
+@(private="file")
+write_vtable := &io.Stream_VTable{
+	impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
+		fd := u32(uintptr(s.stream_data))
+		write(fd, p)
+		return len(p), nil
+	},	
+}
+
+@(private="file")
+stdout := io.Writer{
+	stream = {
+		stream_vtable = write_vtable,
+		stream_data = rawptr(uintptr(1)),
+	},
+}
+@(private="file")
+stderr := io.Writer{
+	stream = {
+		stream_vtable = write_vtable,
+		stream_data = rawptr(uintptr(2)),
+	},
+}
+
+// print* procedures return the number of bytes written
+print   :: proc(args: ..any, sep := " ") -> int { return wprint(w=stdout, args=args, sep=sep) }
+println :: proc(args: ..any, sep := " ") -> int { return wprintln(w=stdout, args=args, sep=sep) }
+printf  :: proc(fmt: string, args: ..any) -> int { return wprintf(stdout, fmt, ..args) }
+
+eprint   :: proc(args: ..any, sep := " ") -> int { return wprint(w=stderr, args=args, sep=sep) }
+eprintln :: proc(args: ..any, sep := " ") -> int { return wprintln(w=stderr, args=args, sep=sep) }
+eprintf  :: proc(fmt: string, args: ..any) -> int { return wprintf(stderr, fmt, ..args) }

+ 1 - 1
core/fmt/fmt_os.odin

@@ -1,4 +1,4 @@
-//+build !freestanding
+//+build !freestanding !js
 package fmt
 
 import "core:runtime"

+ 0 - 60
core/math/math.odin

@@ -36,66 +36,6 @@ MAX_F16_PRECISION ::  4 // Maximum number of meaningful digits after the decimal
 RAD_PER_DEG :: TAU/360.0
 DEG_PER_RAD :: 360.0/TAU
 
-
-@(default_calling_convention="none")
-foreign _ {
-	@(link_name="llvm.sqrt.f16")
-	sqrt_f16 :: proc(x: f16) -> f16 ---
-	@(link_name="llvm.sqrt.f32")
-	sqrt_f32 :: proc(x: f32) -> f32 ---
-	@(link_name="llvm.sqrt.f64")
-	sqrt_f64 :: proc(x: f64) -> f64 ---
-
-	@(link_name="llvm.sin.f16")
-	sin_f16 :: proc(θ: f16) -> f16 ---
-	@(link_name="llvm.sin.f32")
-	sin_f32 :: proc(θ: f32) -> f32 ---
-	@(link_name="llvm.sin.f64")
-	sin_f64 :: proc(θ: f64) -> f64 ---
-
-	@(link_name="llvm.cos.f16")
-	cos_f16 :: proc(θ: f16) -> f16 ---
-	@(link_name="llvm.cos.f32")
-	cos_f32 :: proc(θ: f32) -> f32 ---
-	@(link_name="llvm.cos.f64")
-	cos_f64 :: proc(θ: f64) -> f64 ---
-
-	@(link_name="llvm.pow.f16")
-	pow_f16 :: proc(x, power: f16) -> f16 ---
-	@(link_name="llvm.pow.f32")
-	pow_f32 :: proc(x, power: f32) -> f32 ---
-	@(link_name="llvm.pow.f64")
-	pow_f64 :: proc(x, power: f64) -> f64 ---
-
-	@(link_name="llvm.fmuladd.f16")
-	fmuladd_f16 :: proc(a, b, c: f16) -> f16 ---
-	@(link_name="llvm.fmuladd.f32")
-	fmuladd_f32 :: proc(a, b, c: f32) -> f32 ---
-	@(link_name="llvm.fmuladd.f64")
-	fmuladd_f64 :: proc(a, b, c: f64) -> f64 ---
-
-	@(link_name="llvm.log.f16")
-	ln_f16 :: proc(x: f16) -> f16 ---
-	@(link_name="llvm.log.f32")
-	ln_f32 :: proc(x: f32) -> f32 ---
-	@(link_name="llvm.log.f64")
-	ln_f64 :: proc(x: f64) -> f64 ---
-
-	@(link_name="llvm.exp.f16")
-	exp_f16 :: proc(x: f16) -> f16 ---
-	@(link_name="llvm.exp.f32")
-	exp_f32 :: proc(x: f32) -> f32 ---
-	@(link_name="llvm.exp.f64")
-	exp_f64 :: proc(x: f64) -> f64 ---
-
-	@(link_name="llvm.ldexp.f16")
-	ldexp_f16 :: proc(val: f16, exp: i32) -> f16 ---
-	@(link_name="llvm.ldexp.f32")
-	ldexp_f32 :: proc(val: f32, exp: i32) -> f32 ---
-	@(link_name="llvm.ldexp.f64")
-	ldexp_f64 :: proc(val: f64, exp: i32) -> f64 ---
-}
-
 sqrt_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(sqrt_f16(f16(x))) }
 sqrt_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(sqrt_f16(f16(x))) }
 sqrt_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(sqrt_f32(f32(x))) }

+ 60 - 0
core/math/math_basic.odin

@@ -0,0 +1,60 @@
+package math
+
+@(default_calling_convention="none")
+foreign _ {
+	@(link_name="llvm.sqrt.f16")
+	sqrt_f16 :: proc(x: f16) -> f16 ---
+	@(link_name="llvm.sqrt.f32")
+	sqrt_f32 :: proc(x: f32) -> f32 ---
+	@(link_name="llvm.sqrt.f64")
+	sqrt_f64 :: proc(x: f64) -> f64 ---
+
+	@(link_name="llvm.sin.f16")
+	sin_f16 :: proc(θ: f16) -> f16 ---
+	@(link_name="llvm.sin.f32")
+	sin_f32 :: proc(θ: f32) -> f32 ---
+	@(link_name="llvm.sin.f64")
+	sin_f64 :: proc(θ: f64) -> f64 ---
+
+	@(link_name="llvm.cos.f16")
+	cos_f16 :: proc(θ: f16) -> f16 ---
+	@(link_name="llvm.cos.f32")
+	cos_f32 :: proc(θ: f32) -> f32 ---
+	@(link_name="llvm.cos.f64")
+	cos_f64 :: proc(θ: f64) -> f64 ---
+
+	@(link_name="llvm.pow.f16")
+	pow_f16 :: proc(x, power: f16) -> f16 ---
+	@(link_name="llvm.pow.f32")
+	pow_f32 :: proc(x, power: f32) -> f32 ---
+	@(link_name="llvm.pow.f64")
+	pow_f64 :: proc(x, power: f64) -> f64 ---
+
+	@(link_name="llvm.fmuladd.f16")
+	fmuladd_f16 :: proc(a, b, c: f16) -> f16 ---
+	@(link_name="llvm.fmuladd.f32")
+	fmuladd_f32 :: proc(a, b, c: f32) -> f32 ---
+	@(link_name="llvm.fmuladd.f64")
+	fmuladd_f64 :: proc(a, b, c: f64) -> f64 ---
+
+	@(link_name="llvm.log.f16")
+	ln_f16 :: proc(x: f16) -> f16 ---
+	@(link_name="llvm.log.f32")
+	ln_f32 :: proc(x: f32) -> f32 ---
+	@(link_name="llvm.log.f64")
+	ln_f64 :: proc(x: f64) -> f64 ---
+
+	@(link_name="llvm.exp.f16")
+	exp_f16 :: proc(x: f16) -> f16 ---
+	@(link_name="llvm.exp.f32")
+	exp_f32 :: proc(x: f32) -> f32 ---
+	@(link_name="llvm.exp.f64")
+	exp_f64 :: proc(x: f64) -> f64 ---
+
+	@(link_name="llvm.ldexp.f16")
+	ldexp_f16 :: proc(val: f16, exp: i32) -> f16 ---
+	@(link_name="llvm.ldexp.f32")
+	ldexp_f32 :: proc(val: f32, exp: i32) -> f32 ---
+	@(link_name="llvm.ldexp.f64")
+	ldexp_f64 :: proc(val: f64, exp: i32) -> f64 ---
+}

+ 4 - 0
core/os/os_freestanding.odin

@@ -0,0 +1,4 @@
+//+freestanding
+package os
+
+#panic("package os does not support a freestanding target")

+ 4 - 0
core/os/os_js.odin

@@ -0,0 +1,4 @@
+//+js
+package os
+
+#panic("package os does not support a js target")

+ 1 - 1
core/runtime/core.odin

@@ -528,5 +528,5 @@ default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code
 		}
 		print_byte('\n')
 	}
-	intrinsics.trap()
+	trap()
 }

+ 1 - 0
core/runtime/default_allocators_general.odin

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

+ 5 - 0
core/runtime/default_allocators_js.odin

@@ -0,0 +1,5 @@
+//+build js
+package runtime
+
+default_allocator_proc :: nil_allocator_proc
+default_allocator :: nil_allocator

+ 1 - 1
core/runtime/default_temporary_allocator.odin

@@ -3,7 +3,7 @@ package runtime
 DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE: int : #config(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE, 1<<22)
 
 
-when ODIN_OS == "freestanding" || ODIN_DEFAULT_TO_NIL_ALLOCATOR {
+when ODIN_OS == "freestanding" || ODIN_OS == "js" || ODIN_DEFAULT_TO_NIL_ALLOCATOR {
 	Default_Temp_Allocator :: struct {}
 	
 	default_temp_allocator_init :: proc(s: ^Default_Temp_Allocator, size: int, backup_allocator := context.allocator) {}

+ 1 - 1
core/runtime/internal.odin

@@ -9,7 +9,7 @@ RUNTIME_LINKAGE :: "strong" when (
 	!ODIN_NO_CRT) &&
 	!(ODIN_ARCH == "wasm32" || 
 	  ODIN_ARCH == "wasm64")) else "internal"
-RUNTIME_REQUIRE :: !(ODIN_ARCH == "wasm32" || ODIN_ARCH == "wasm64")
+RUNTIME_REQUIRE :: true
 
 
 @(private)

+ 1 - 1
core/runtime/os_specific_any.odin

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

+ 12 - 0
core/runtime/os_specific_js.odin

@@ -0,0 +1,12 @@
+//+build js
+package runtime
+
+foreign import "odin_env"
+
+_os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
+	foreign odin_env {
+		write :: proc "c" (fd: u32, p: []byte) ---
+	}
+	write(1, data)
+	return len(data), 0
+}

+ 15 - 0
core/runtime/procs_js_wasm32.odin

@@ -0,0 +1,15 @@
+//+build js wasm32
+package runtime
+
+init_default_context_for_js: Context
+@(init, private="file")
+init_default_context :: proc() {
+	init_default_context_for_js = context
+}
+
+@(export)
+@(link_name="default_context_ptr")
+default_context_ptr :: proc "contextless" () -> ^Context {
+	return &init_default_context_for_js
+}
+

+ 5 - 1
core/runtime/procs_wasm32.odin

@@ -2,7 +2,9 @@
 package runtime
 
 @(link_name="__ashlti3", linkage="strong")
-__ashlti3 :: proc "c" (a: i64, b: u32) -> i64 {
+__ashlti3 :: proc "c" (a: i64, b_: i32) -> i64 {
+	/*
+	b := u32(b_)
 	input := transmute([2]i32)a
 	result: [2]i32
 	if b & 32 != 0 {
@@ -16,4 +18,6 @@ __ashlti3 :: proc "c" (a: i64, b: u32) -> i64 {
 		result[1] = (input[1]<<b) | (input[0]>>(32-b))
 	}
 	return transmute(i64)result
+	*/
+	return 0
 }

+ 16 - 0
core/time/time_freestanding.odin

@@ -0,0 +1,16 @@
+//+build freestanding
+package time
+
+IS_SUPPORTED :: false
+
+now :: proc() -> Time {
+	return {}
+}
+
+sleep :: proc(d: Duration) {
+}
+
+_tick_now :: proc "contextless" () -> Tick {
+	return {}
+}
+

+ 21 - 0
core/time/time_js.odin

@@ -0,0 +1,21 @@
+//+build js
+package time
+
+IS_SUPPORTED :: false
+
+now :: proc() -> Time {
+	return {}
+}
+
+sleep :: proc(d: Duration) {
+}
+
+_tick_now :: proc "contextless" () -> Tick {
+	// mul_div_u64 :: proc "contextless" (val, num, den: i64) -> i64 {
+	// 	q := val / den
+	// 	r := val % den
+	// 	return q * num + r * num / den
+	// }
+	return {}
+}
+

+ 23 - 0
core/time/time_wasi.odin

@@ -0,0 +1,23 @@
+//+build wasi
+package time
+
+import wasi "core:sys/wasm/wasi"
+
+IS_SUPPORTED :: false
+
+now :: proc() -> Time {
+	return {}
+}
+
+sleep :: proc(d: Duration) {
+}
+
+_tick_now :: proc "contextless" () -> Tick {
+	// mul_div_u64 :: proc "contextless" (val, num, den: i64) -> i64 {
+	// 	q := val / den
+	// 	r := val % den
+	// 	return q * num + r * num / den
+	// }
+	return {}
+}
+