Browse Source

Add `memmove` and `memset` support for `wasm`

gingerBill 3 years ago
parent
commit
2a5b8f53fe
4 changed files with 51 additions and 12 deletions
  1. 34 7
      core/runtime/procs.odin
  2. 3 2
      src/build_settings.cpp
  3. 9 3
      src/llvm_backend.cpp
  4. 5 0
      src/llvm_backend_opt.cpp

+ 34 - 7
core/runtime/procs.odin

@@ -1,12 +1,39 @@
 package runtime
 package runtime
 
 
-memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr {
-	if ptr != nil && len != 0 {
-		b := byte(val)
-		p := ([^]byte)(ptr)
-		for i in 0..<len {
-			p[i] = b
+when ODIN_ARCH == "wasm32" || ODIN_ARCH == "wasm64" {
+	@(link_name="memset")
+	memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr {
+		if ptr != nil && len != 0 {
+			b := byte(val)
+			p := ([^]byte)(ptr)
+			for i in 0..<len {
+				p[i] = b
+			}
 		}
 		}
+		return ptr
+	}
+	
+	@(link_name="memmove")
+	memmove :: proc "c" (dst, src: rawptr, len: int) -> rawptr {
+		if dst != src {
+			d, s := ([^]byte)(dst), ([^]byte)(src)
+			d_end, s_end := d[len:], s[len:]
+			for i := len-1; i >= 0; i -= 1 {
+				d[i] = s[i]
+			}
+		}
+		return dst
+		
+	}
+} else {
+	memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr {
+		if ptr != nil && len != 0 {
+			b := byte(val)
+			p := ([^]byte)(ptr)
+			for i in 0..<len {
+				p[i] = b
+			}
+		}
+		return ptr
 	}
 	}
-	return ptr
 }
 }

+ 3 - 2
src/build_settings.cpp

@@ -909,8 +909,9 @@ void init_build_context(TargetMetrics *cross_target) {
 			break;
 			break;
 		}
 		}
 	} else if (is_arch_wasm()) {
 	} else if (is_arch_wasm()) {
-		gbString link_flags = gb_string_make(heap_allocator(), "--export-all  ");
-		link_flags = gb_string_appendc(link_flags, "--export-table ");
+		gbString link_flags = gb_string_make(heap_allocator(), " ");
+		// link_flags = gb_string_appendc(link_flags, "--export-all ");
+		// link_flags = gb_string_appendc(link_flags, "--export-table ");
 		link_flags = gb_string_appendc(link_flags, "--allow-undefined ");
 		link_flags = gb_string_appendc(link_flags, "--allow-undefined ");
 		if (bc->metrics.arch == TargetArch_wasm64) {
 		if (bc->metrics.arch == TargetArch_wasm64) {
 			link_flags = gb_string_appendc(link_flags, "-mwas64 ");
 			link_flags = gb_string_appendc(link_flags, "-mwas64 ");

+ 9 - 3
src/llvm_backend.cpp

@@ -771,6 +771,8 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
 	Type *results = alloc_type_tuple();
 	Type *results = alloc_type_tuple();
 
 
 	Type *t_ptr_cstring = alloc_type_pointer(t_cstring);
 	Type *t_ptr_cstring = alloc_type_pointer(t_cstring);
+	
+	bool call_cleanup = true;
 
 
 	bool has_args = false;
 	bool has_args = false;
 	bool is_dll_main = false;
 	bool is_dll_main = false;
@@ -782,10 +784,12 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
 		params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("hinstDLL"),   t_rawptr, false, true);
 		params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("hinstDLL"),   t_rawptr, false, true);
 		params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("fdwReason"),  t_u32,    false, true);
 		params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("fdwReason"),  t_u32,    false, true);
 		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);
+		call_cleanup = false;
 	} 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) {
 	} else if (build_context.metrics.os == TargetOs_wasi) {
 		name = str_lit("_start");
 		name = str_lit("_start");
+		call_cleanup = false;
 	} else {
 	} else {
 		has_args = true;
 		has_args = true;
 		slice_init(&params->Tuple.variables, permanent_allocator(), 2);
 		slice_init(&params->Tuple.variables, permanent_allocator(), 2);
@@ -876,8 +880,10 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
 	}
 	}
 
 
 	
 	
-	lbValue cleanup_runtime_value = lb_find_runtime_value(m, str_lit("_cleanup_runtime"));
-	lb_emit_call(p, cleanup_runtime_value, {}, ProcInlining_none, false);
+	if (call_cleanup) {
+		lbValue cleanup_runtime_value = lb_find_runtime_value(m, str_lit("_cleanup_runtime"));
+		lb_emit_call(p, cleanup_runtime_value, {}, ProcInlining_none, false);
+	}
 	
 	
 
 
 	if (is_dll_main) {
 	if (is_dll_main) {
@@ -890,7 +896,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
 	
 	
 	
 	
 	if (build_context.metrics.os == TargetOs_wasi) {
 	if (build_context.metrics.os == TargetOs_wasi) {
-		LLVMSetLinkage(p->value, LLVMDLLExportLinkage);	
+		LLVMSetLinkage(p->value, LLVMDLLExportLinkage);
 	} else {
 	} else {
 		LLVMSetLinkage(p->value, LLVMExternalLinkage);
 		LLVMSetLinkage(p->value, LLVMExternalLinkage);
 	}
 	}

+ 5 - 0
src/llvm_backend_opt.cpp

@@ -383,6 +383,11 @@ void lb_run_remove_unused_function_pass(LLVMModuleRef mod) {
 				continue;
 				continue;
 			}
 			}
 			
 			
+			if (name == "memset" ||
+			    name == "memmove" ||
+			    name == "memcpy") {
+				continue;
+			}
 			
 			
 			LLVMLinkage linkage = LLVMGetLinkage(curr_func);
 			LLVMLinkage linkage = LLVMGetLinkage(curr_func);