Browse Source

wasm: add foreign import and linking of wasm object files

Laytan Laats 1 year ago
parent
commit
6f1cc8071c
6 changed files with 26 additions and 16 deletions
  1. 0 9
      src/build_settings.cpp
  2. 5 2
      src/check_decl.cpp
  3. 1 2
      src/checker.cpp
  4. 14 0
      src/linker.cpp
  5. 5 1
      src/llvm_backend_utility.cpp
  6. 1 2
      src/parser.cpp

+ 0 - 9
src/build_settings.cpp

@@ -860,15 +860,6 @@ gb_internal bool is_arch_x86(void) {
 	return false;
 }
 
-gb_internal bool allow_check_foreign_filepath(void) {
-	switch (build_context.metrics.arch) {
-	case TargetArch_wasm32:
-	case TargetArch_wasm64p32:
-		return false;
-	}
-	return true;
-}
-
 // TODO(bill): OS dependent versions for the BuildContext
 // join_path
 // is_dir

+ 5 - 2
src/check_decl.cpp

@@ -1178,9 +1178,12 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 			if (foreign_library->LibraryName.paths.count >= 1) {
 				module_name = foreign_library->LibraryName.paths[0];
 			}
-			name = concatenate3_strings(permanent_allocator(), module_name, WASM_MODULE_NAME_SEPARATOR, name);
+
+			if (!string_ends_with(module_name, str_lit(".o"))) {
+				name = concatenate3_strings(permanent_allocator(), module_name, WASM_MODULE_NAME_SEPARATOR, name);
+			}
 		}
-		
+
 		e->Procedure.is_foreign = true;
 		e->Procedure.link_name = name;
 

+ 1 - 2
src/checker.cpp

@@ -5000,9 +5000,8 @@ gb_internal void check_foreign_import_fullpaths(Checker *c) {
 
 				String file_str = op.value.value_string;
 				file_str = string_trim_whitespace(file_str);
-
 				String fullpath = file_str;
-				if (allow_check_foreign_filepath()) {
+				if (!is_arch_wasm() || string_ends_with(file_str, str_lit(".o"))) {
 					String foreign_path = {};
 					bool ok = determine_path_from_string(nullptr, decl, base_dir, file_str, &foreign_path, /*use error not syntax_error*/true);
 					if (ok) {

+ 14 - 0
src/linker.cpp

@@ -85,6 +85,20 @@ gb_internal i32 linker_stage(LinkerData *gen) {
 			if (extra_linker_flags.len != 0) {
 				lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(extra_linker_flags));
 			}
+
+			for_array(i, e->LibraryName.paths) {
+				String lib = e->LibraryName.paths[i];
+
+				if (lib.len == 0) {
+					continue;
+				}
+
+				if (!string_ends_with(lib, str_lit(".o"))) {
+					continue;
+				}
+
+				inputs = gb_string_append_fmt(inputs, " \"%.*s\"", LIT(lib));
+			}
 		}
 
 		if (build_context.metrics.os == TargetOs_orca) {

+ 5 - 1
src/llvm_backend_utility.cpp

@@ -2029,7 +2029,11 @@ gb_internal void lb_set_wasm_procedure_import_attributes(LLVMValueRef value, Ent
 		GB_ASSERT(foreign_library->LibraryName.paths.count == 1);
 		
 		module_name = foreign_library->LibraryName.paths[0];
-		
+
+		if (string_ends_with(module_name, str_lit(".o"))) {
+			return;
+		}
+
 		if (string_starts_with(import_name, module_name)) {
 			import_name = substring(import_name, module_name.len+WASM_MODULE_NAME_SEPARATOR.len, import_name.len);
 		}

+ 1 - 2
src/parser.cpp

@@ -5813,7 +5813,6 @@ gb_internal bool determine_path_from_string(BlockingMutex *file_mutex, Ast *node
 		return false;
 	}
 
-
 	if (collection_name.len > 0) {
 		// NOTE(bill): `base:runtime` == `core:runtime`
 		if (collection_name == "core") {
@@ -5968,7 +5967,7 @@ gb_internal void parse_setup_file_decls(Parser *p, AstFile *f, String const &bas
 				Token fp_token = fp->BasicLit.token;
 				String file_str = string_trim_whitespace(string_value_from_token(f, fp_token));
 				String fullpath = file_str;
-				if (allow_check_foreign_filepath()) {
+				if (!is_arch_wasm() || string_ends_with(fullpath, str_lit(".o"))) {
 					String foreign_path = {};
 					bool ok = determine_path_from_string(&p->file_decl_mutex, node, base_dir, file_str, &foreign_path);
 					if (!ok) {