Browse Source

Add `wasm-ld` support for wasm code generation

gingerBill 5 years ago
parent
commit
626b4740b1
3 changed files with 32 additions and 10 deletions
  1. 1 1
      src/build_settings.cpp
  2. 19 5
      src/llvm_backend.cpp
  3. 12 4
      src/main.cpp

+ 1 - 1
src/build_settings.cpp

@@ -684,7 +684,7 @@ void init_build_context(TargetMetrics *cross_target) {
 			break;
 		}
 	} else if (bc->metrics.arch == TargetArch_wasm32) {
-
+		bc->link_flags = str_lit("--no-entry --export-table --export-all --allow-undefined ");
 	} else {
 		gb_printf_err("Compiler Error: Unsupported architecture\n");;
 		gb_exit(1);

+ 19 - 5
src/llvm_backend.cpp

@@ -2017,6 +2017,9 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
 	p->branch_blocks.allocator = a;
 	p->context_stack.allocator = a;
 
+	if (p->is_foreign) {
+		lb_add_foreign_library_path(p->module, entity->Procedure.foreign_library);
+	}
 
 	char *c_link_name = alloc_cstring(heap_allocator(), p->name);
 	LLVMTypeRef func_ptr_type = lb_type(m, p->type);
@@ -2036,10 +2039,24 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
 		LLVMSetVisibility(p->value, LLVMDefaultVisibility);
 
 		if (build_context.metrics.os == TargetOs_js) {
-			LLVMAddTargetDependentFunctionAttr(p->value, "wasm-export-name", alloc_cstring(heap_allocator(), p->name));
+			char const *export_name = alloc_cstring(heap_allocator(), p->name);
+			LLVMAddTargetDependentFunctionAttr(p->value, "export", export_name);
+			LLVMAddTargetDependentFunctionAttr(p->value, "export-name", export_name);
+			LLVMAddTargetDependentFunctionAttr(p->value, "wasm-export-name", export_name);
 			LLVMAddTargetDependentFunctionAttr(p->value, "wasm-exported", nullptr);
 		}
 	}
+	if (p->is_foreign) {
+		if (build_context.metrics.os == TargetOs_js) {
+			char const *import_name = alloc_cstring(heap_allocator(), p->name);
+			char const *module_name = "env";
+			if (entity->Procedure.foreign_library != nullptr) {
+				module_name = alloc_cstring(heap_allocator(), entity->Procedure.foreign_library->token.string);
+			}
+			LLVMAddTargetDependentFunctionAttr(p->value, "wasm-import-name",   import_name);
+			LLVMAddTargetDependentFunctionAttr(p->value, "wasm-import-module", module_name);
+		}
+	}
 
 	// NOTE(bill): offset==0 is the return value
 	isize offset = 1;
@@ -2085,9 +2102,6 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
 	}
 
 
-	if (entity->Procedure.is_foreign) {
-		lb_add_foreign_library_path(p->module, entity->Procedure.foreign_library);
-	}
 
 
 	{ // Debug Information
@@ -12192,7 +12206,7 @@ void lb_generate_code(lbGenerator *gen) {
 		filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".o"));
 		break;
 	case TargetOs_js:
-		filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".wasm"));
+		filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".wasm-obj"));
 		break;
 	}
 

+ 12 - 4
src/main.cpp

@@ -140,6 +140,18 @@ i32 linker_stage(lbGenerator *gen) {
 
 	String output_base = gen->output_base;
 
+	if (build_context.metrics.os == TargetOs_js) {
+		timings_start_section(timings, str_lit("wasm-ld"));
+		exit_code = system_exec_command_line_app("wasm-ld",
+			"\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm-obj\" -o \"%.*s.wasm\" %.*s %.*s",
+			LIT(build_context.ODIN_ROOT),
+			LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags));
+		if (exit_code != 0) {
+			return exit_code;
+		}
+		return exit_code;
+	}
+
 	if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) {
 #ifdef GB_SYSTEM_UNIX
 		system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s %.*s",
@@ -1659,10 +1671,6 @@ int main(int arg_count, char const **arg_ptr) {
 			print_usage_line(0, "%.*s - js platform only supported with the -llvm-api backend", LIT(args[0]));
 			return 1;
 		}
-		if (build_context.build_mode != BuildMode_Object) {
-			print_usage_line(0, "%.*s - js platform only supports -build-mode:object", LIT(args[0]));
-			return 1;
-		}
 	}
 
 	init_universal();