aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2021-10-31 19:19:48 +0000
committerGitHub <noreply@github.com>2021-10-31 19:19:48 +0000
commitb1de429d2cf5c2d1643acc73ec3ced22e57d6a07 (patch)
tree99d74a813fc16bbe3389f69cb0ca516744cbb561 /src
parent3de1719c172771c2cb5ed41725274e71906b7e0a (diff)
parent5f51337a01fa4a1e7a461604d564fa64601727cf (diff)
Merge pull request #1255 from odin-lang/wasi-wasm
`wasi_wasm32` support
Diffstat (limited to 'src')
-rw-r--r--src/build_settings.cpp64
-rw-r--r--src/check_decl.cpp8
-rw-r--r--src/checker.cpp3
-rw-r--r--src/entity.cpp3
-rw-r--r--src/llvm_abi.cpp87
-rw-r--r--src/llvm_backend.cpp42
-rw-r--r--src/llvm_backend.hpp21
-rw-r--r--src/llvm_backend_expr.cpp2
-rw-r--r--src/llvm_backend_opt.cpp60
-rw-r--r--src/llvm_backend_proc.cpp13
-rw-r--r--src/llvm_backend_utility.cpp1
-rw-r--r--src/main.cpp7
-rw-r--r--src/string.cpp7
13 files changed, 289 insertions, 29 deletions
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index 69e1ec5f0..3bd6622c7 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -16,6 +16,8 @@ enum TargetOsKind {
TargetOs_linux,
TargetOs_essence,
TargetOs_freebsd,
+
+ TargetOs_wasi,
TargetOs_freestanding,
@@ -29,6 +31,7 @@ enum TargetArchKind {
TargetArch_386,
TargetArch_arm64,
TargetArch_wasm32,
+ TargetArch_wasm64,
TargetArch_COUNT,
};
@@ -49,6 +52,8 @@ String target_os_names[TargetOs_COUNT] = {
str_lit("linux"),
str_lit("essence"),
str_lit("freebsd"),
+
+ str_lit("wasi"),
str_lit("freestanding"),
};
@@ -59,6 +64,7 @@ String target_arch_names[TargetArch_COUNT] = {
str_lit("386"),
str_lit("arm64"),
str_lit("wasm32"),
+ str_lit("wasm64"),
};
String target_endian_names[TargetEndian_COUNT] = {
@@ -72,6 +78,7 @@ TargetEndianKind target_endians[TargetArch_COUNT] = {
TargetEndian_Little,
TargetEndian_Little,
TargetEndian_Little,
+ TargetEndian_Little,
};
#ifndef ODIN_VERSION_RAW
@@ -335,6 +342,26 @@ gb_global TargetMetrics target_freestanding_wasm32 = {
str_lit(""),
};
+gb_global TargetMetrics target_freestanding_wasm64 = {
+ TargetOs_freestanding,
+ TargetArch_wasm64,
+ 8,
+ 16,
+ str_lit("wasm64-freestanding-js"),
+ str_lit(""),
+};
+
+gb_global TargetMetrics target_wasi_wasm32 = {
+ TargetOs_wasi,
+ TargetArch_wasm32,
+ 4,
+ 8,
+ str_lit("wasm32-wasi-js"),
+ str_lit(""),
+};
+
+
+
struct NamedTargetMetrics {
@@ -353,6 +380,8 @@ gb_global NamedTargetMetrics named_targets[] = {
{ str_lit("freebsd_386"), &target_freebsd_386 },
{ str_lit("freebsd_amd64"), &target_freebsd_amd64 },
{ str_lit("freestanding_wasm32"), &target_freestanding_wasm32 },
+ // { str_lit("freestanding_wasm64"), &target_freestanding_wasm64 },
+ { str_lit("wasi_wasm32"), &target_wasi_wasm32 },
};
NamedTargetMetrics *selected_target_metrics;
@@ -458,11 +487,21 @@ bool find_library_collection_path(String name, String *path) {
}
bool is_arch_wasm(void) {
- return build_context.metrics.arch == TargetArch_wasm32;
+ switch (build_context.metrics.arch) {
+ case TargetArch_wasm32:
+ case TargetArch_wasm64:
+ return true;
+ }
+ return false;
}
bool allow_check_foreign_filepath(void) {
- return build_context.metrics.arch != TargetArch_wasm32;
+ switch (build_context.metrics.arch) {
+ case TargetArch_wasm32:
+ case TargetArch_wasm64:
+ return false;
+ }
+ return true;
}
@@ -869,11 +908,24 @@ void init_build_context(TargetMetrics *cross_target) {
bc->link_flags = str_lit("-arch arm64 ");
break;
}
-
- } else if (bc->metrics.arch == TargetArch_wasm32) {
- bc->link_flags = str_lit("--no-entry --export-table --export-all --allow-undefined ");
+ } else if (is_arch_wasm()) {
+ 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 ");
+ 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);
+
+ // Disallow on wasm
+ build_context.use_separate_modules = false;
} else {
- gb_printf_err("Compiler Error: Unsupported architecture\n");;
+ gb_printf_err("Compiler Error: Unsupported architecture\n");
gb_exit(1);
}
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index 0591eca4d..c2d23e70c 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -899,6 +899,10 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
mutex_unlock(&ctx->info->foreign_mutex);
}
}
+
+ if (e->Procedure.link_name.len > 0 ) {
+ e->flags |= EntityFlag_CustomLinkName;
+ }
}
void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) {
@@ -990,6 +994,10 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr,
string_map_set(fp, key, e);
}
}
+
+ if (e->Variable.link_name.len > 0) {
+ e->flags |= EntityFlag_CustomLinkName;
+ }
if (init_expr == nullptr) {
if (type_expr == nullptr) {
diff --git a/src/checker.cpp b/src/checker.cpp
index 8db9e1bd6..f0f463816 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -2011,6 +2011,9 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
str_lit("gnu_h2f_ieee"),
str_lit("gnu_f2h_ieee"),
str_lit("extendhfsf2"),
+
+ // WASM Specific
+ str_lit("__ashlti3"),
};
for (isize i = 0; i < gb_count_of(required_runtime_entities); i++) {
force_add_dependency_entity(c, c->info.runtime_package->scope, required_runtime_entities[i]);
diff --git a/src/entity.cpp b/src/entity.cpp
index 86fefcf89..d95c74f22 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -74,9 +74,10 @@ enum EntityFlag : u64 {
EntityFlag_Test = 1ull<<30,
EntityFlag_Init = 1ull<<31,
+
+ EntityFlag_CustomLinkName = 1ull<<40,
EntityFlag_Overridden = 1ull<<63,
-
};
enum EntityState : u32 {
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp
index 9e7f4b290..9c7ced91e 100644
--- a/src/llvm_abi.cpp
+++ b/src/llvm_abi.cpp
@@ -1039,6 +1039,75 @@ namespace lbAbiArm64 {
}
}
+namespace lbAbiWasm32 {
+ Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count);
+ lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined);
+
+ LB_ABI_INFO(abi_info) {
+ lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
+ ft->ctx = c;
+ ft->args = compute_arg_types(c, arg_types, arg_count);
+ ft->ret = compute_return_type(c, return_type, return_is_defined);
+ ft->calling_convention = calling_convention;
+ return ft;
+ }
+
+ lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) {
+ if (!is_return && type == LLVMIntTypeInContext(c, 128)) {
+ LLVMTypeRef cast_type = LLVMVectorType(LLVMInt64TypeInContext(c), 2);
+ return lb_arg_type_direct(type, cast_type, nullptr, nullptr);
+ }
+
+ if (!is_return && lb_sizeof(type) > 8) {
+ return lb_arg_type_indirect(type, nullptr);
+ }
+
+ LLVMAttributeRef attr = nullptr;
+ LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
+ if (type == i1) {
+ attr = lb_create_enum_attribute(c, "zeroext");
+ }
+ return lb_arg_type_direct(type, nullptr, nullptr, attr);
+ }
+
+ Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) {
+ auto args = array_make<lbArgType>(heap_allocator(), arg_count);
+
+ for (unsigned i = 0; i < arg_count; i++) {
+ LLVMTypeRef t = arg_types[i];
+ LLVMTypeKind kind = LLVMGetTypeKind(t);
+ i64 sz = lb_sizeof(t);
+ if (kind == LLVMStructTypeKind || kind == LLVMArrayTypeKind) {
+ if (sz == 0) {
+ args[i] = lb_arg_type_ignore(t);
+ } else {
+ args[i] = lb_arg_type_indirect(t, nullptr);
+ }
+ } else {
+ args[i] = non_struct(c, t, false);
+ }
+ }
+ return args;
+ }
+
+ lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined) {
+ if (!return_is_defined) {
+ return lb_arg_type_direct(LLVMVoidTypeInContext(c));
+ } else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) {
+ i64 sz = lb_sizeof(return_type);
+ switch (sz) {
+ case 1: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), nullptr, nullptr);
+ case 2: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), nullptr, nullptr);
+ case 4: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), nullptr, nullptr);
+ case 8: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 64), nullptr, nullptr);
+ }
+ LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", return_type);
+ return lb_arg_type_indirect(return_type, attr);
+ }
+ return non_struct(c, return_type, true);
+ }
+}
+
LB_ABI_INFO(lb_get_abi_info) {
switch (calling_convention) {
@@ -1061,19 +1130,27 @@ LB_ABI_INFO(lb_get_abi_info) {
}
}
- if (build_context.metrics.arch == TargetArch_amd64) {
+ switch (build_context.metrics.arch) {
+ case TargetArch_amd64:
if (build_context.metrics.os == TargetOs_windows) {
return lbAbiAmd64Win64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention);
} else {
return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention);
}
- } else if (build_context.metrics.arch == TargetArch_386) {
+ case TargetArch_386:
return lbAbi386::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention);
- } else if (build_context.metrics.arch == TargetArch_arm64) {
+ case TargetArch_arm64:
return lbAbiArm64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention);
- } else if (build_context.metrics.arch == TargetArch_wasm32) {
- return lbAbi386::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention);
+ case TargetArch_wasm32:
+ // TODO(bill): implement wasm32's ABI correct
+ // NOTE(bill): this ABI is only an issue for WASI compatibility
+ return lbAbiWasm32::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention);
+ case TargetArch_wasm64:
+ // TODO(bill): implement wasm64's ABI correct
+ // NOTE(bill): this ABI is only an issue for WASI compatibility
+ return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention);
}
+
GB_PANIC("Unsupported ABI");
return {};
}
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index 4d1245c98..1d382aa6d 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -771,6 +771,8 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
Type *results = alloc_type_tuple();
Type *t_ptr_cstring = alloc_type_pointer(t_cstring);
+
+ bool call_cleanup = true;
bool has_args = false;
bool is_dll_main = false;
@@ -782,8 +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[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);
+ call_cleanup = false;
} else if (build_context.metrics.os == TargetOs_windows && build_context.metrics.arch == TargetArch_386) {
name = str_lit("mainCRTStartup");
+ } else if (is_arch_wasm()) {
+ name = str_lit("_start");
+ call_cleanup = false;
} else {
has_args = true;
slice_init(&params->Tuple.variables, permanent_allocator(), 2);
@@ -874,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) {
@@ -885,6 +893,19 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
}
lb_end_procedure_body(p);
+
+
+ if (is_arch_wasm()) {
+ LLVMSetLinkage(p->value, LLVMDLLExportLinkage);
+ LLVMSetDLLStorageClass(p->value, LLVMDLLExportStorageClass);
+ LLVMSetVisibility(p->value, LLVMDefaultVisibility);
+
+ char const *export_name = alloc_cstring(permanent_allocator(), p->name);
+ LLVMAddTargetDependentFunctionAttr(p->value, "wasm-export-name", export_name);
+ } else {
+ LLVMSetLinkage(p->value, LLVMExternalLinkage);
+ }
+
if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %s\n", "main");
@@ -1064,14 +1085,10 @@ struct lbLLVMModulePassWorkerData {
};
WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
- GB_ASSERT(MULTITHREAD_OBJECT_GENERATION);
-
auto wd = cast(lbLLVMModulePassWorkerData *)data;
-
LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager();
lb_populate_module_pass_manager(wd->target_machine, module_pass_manager, build_context.optimization_level);
LLVMRunPassManager(module_pass_manager, wd->m->mod);
-
return 0;
}
@@ -1148,6 +1165,7 @@ void lb_generate_code(lbGenerator *gen) {
LLVMInitializeAArch64Disassembler();
break;
case TargetArch_wasm32:
+ case TargetArch_wasm64:
LLVMInitializeWebAssemblyTargetInfo();
LLVMInitializeWebAssemblyTarget();
LLVMInitializeWebAssemblyTargetMC();
@@ -1660,6 +1678,8 @@ void lb_generate_code(lbGenerator *gen) {
for_array(i, gen->modules.entries) {
lbModule *m = gen->modules.entries[i].value;
+
+ lb_run_remove_unused_function_pass(m->mod);
auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
wd->m = m;
@@ -1737,8 +1757,16 @@ void lb_generate_code(lbGenerator *gen) {
}
TIME_SECTION("LLVM Object Generation");
+
+ isize non_empty_module_count = 0;
+ for_array(j, gen->modules.entries) {
+ lbModule *m = gen->modules.entries[j].value;
+ if (!lb_is_module_empty(m)) {
+ non_empty_module_count += 1;
+ }
+ }
- if (do_threading) {
+ if (do_threading && non_empty_module_count > 1) {
for_array(j, gen->modules.entries) {
lbModule *m = gen->modules.entries[j].value;
if (lb_is_module_empty(m)) {
diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp
index 9aa9920f2..5fc5dfebf 100644
--- a/src/llvm_backend.hpp
+++ b/src/llvm_backend.hpp
@@ -585,3 +585,24 @@ enum : LLVMAttributeIndex {
LLVMAttributeIndex_FunctionIndex = ~0u,
LLVMAttributeIndex_FirstArgIndex = 1,
};
+
+
+char const *llvm_linkage_strings[] = {
+ "external linkage",
+ "available externally linkage",
+ "link once any linkage",
+ "link once odr linkage",
+ "link once odr auto hide linkage",
+ "weak any linkage",
+ "weak odr linkage",
+ "appending linkage",
+ "internal linkage",
+ "private linkage",
+ "dllimport linkage",
+ "dllexport linkage",
+ "external weak linkage",
+ "ghost linkage",
+ "common linkage",
+ "linker private linkage",
+ "linker private weak linkage"
+}; \ No newline at end of file
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index c9827ae3a..fd9b10a4f 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -496,6 +496,7 @@ bool lb_is_matrix_simdable(Type *t) {
break;
case TargetArch_386:
case TargetArch_wasm32:
+ case TargetArch_wasm64:
// nope
return false;
}
@@ -513,6 +514,7 @@ bool lb_is_matrix_simdable(Type *t) {
return true;
case TargetArch_386:
case TargetArch_wasm32:
+ case TargetArch_wasm64:
return false;
}
}
diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp
index d5ea90aea..75a377e5b 100644
--- a/src/llvm_backend_opt.cpp
+++ b/src/llvm_backend_opt.cpp
@@ -355,3 +355,63 @@ void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedure *p) {
// are not removed
lb_run_remove_dead_instruction_pass(p);
}
+
+
+void lb_run_remove_unused_function_pass(LLVMModuleRef mod) {
+ isize removal_count = 0;
+ isize pass_count = 0;
+ isize const max_pass_count = 10;
+ // Custom remove dead function pass
+ for (; pass_count < max_pass_count; pass_count++) {
+ bool was_dead_function = false;
+ for (LLVMValueRef func = LLVMGetFirstFunction(mod);
+ func != nullptr;
+ /**/
+ ) {
+ LLVMValueRef curr_func = func;
+ func = LLVMGetNextFunction(func);
+
+ LLVMUseRef first_use = LLVMGetFirstUse(curr_func);
+ if (first_use != nullptr) {
+ continue;
+ }
+ String name = {};
+ name.text = cast(u8 *)LLVMGetValueName2(curr_func, cast(size_t *)&name.len);
+
+ if (LLVMIsDeclaration(curr_func)) {
+ // Ignore for the time being
+ continue;
+ }
+
+ if (name == "memset" ||
+ name == "memmove" ||
+ name == "memcpy") {
+ continue;
+ }
+ if (is_arch_wasm()) {
+ if (name == "__ashlti3") {
+ LLVMSetLinkage(curr_func, LLVMExternalLinkage);
+ continue;
+ }
+ }
+
+ LLVMLinkage linkage = LLVMGetLinkage(curr_func);
+
+ switch (linkage) {
+ case LLVMExternalLinkage:
+ case LLVMDLLImportLinkage:
+ case LLVMDLLExportLinkage:
+ default:
+ continue;
+ case LLVMInternalLinkage:
+ break;
+ }
+ LLVMDeleteFunction(curr_func);
+ was_dead_function = true;
+ removal_count += 1;
+ }
+ if (!was_dead_function) {
+ break;
+ }
+ }
+}
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index 15689da36..29f7b6655 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -195,13 +195,19 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
// then it is very likely it is required by LLVM and thus cannot have internal linkage
if (entity->pkg != nullptr && entity->pkg->kind == Package_Runtime && p->body != nullptr) {
GB_ASSERT(entity->kind == Entity_Procedure);
- if (entity->Procedure.link_name != "") {
- LLVMSetLinkage(p->value, LLVMExternalLinkage);
+ String link_name = entity->Procedure.link_name;
+ if (entity->flags & EntityFlag_CustomLinkName &&
+ link_name != "") {
+ if (string_starts_with(link_name, str_lit("__"))) {
+ LLVMSetLinkage(p->value, LLVMExternalLinkage);
+ } else {
+ LLVMSetLinkage(p->value, LLVMInternalLinkage);
+ }
}
}
}
}
-
+
if (p->is_foreign) {
if (is_arch_wasm()) {
char const *import_name = alloc_cstring(permanent_allocator(), p->name);
@@ -217,6 +223,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
LLVMAddTargetDependentFunctionAttr(p->value, "wasm-import-module", module_name);
}
}
+
// NOTE(bill): offset==0 is the return value
isize offset = 1;
diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp
index 14fb8280e..b58f07d49 100644
--- a/src/llvm_backend_utility.cpp
+++ b/src/llvm_backend_utility.cpp
@@ -1504,6 +1504,7 @@ lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t
break;
case TargetArch_386:
case TargetArch_wasm32:
+ case TargetArch_wasm64:
is_possible = false;
break;
}
diff --git a/src/main.cpp b/src/main.cpp
index 92e541384..173c70a4d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -135,13 +135,12 @@ i32 linker_stage(lbGenerator *gen) {
if (is_arch_wasm()) {
timings_start_section(timings, str_lit("wasm-ld"));
+
result = system_exec_command_line_app("wasm-ld",
- "\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm-obj\" -o \"%.*s.wasm\" %.*s %.*s",
+ "\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm.o\" -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 (result) {
- return result;
- }
+ return result;
}
if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) {
diff --git a/src/string.cpp b/src/string.cpp
index ca53fb2fc..800378689 100644
--- a/src/string.cpp
+++ b/src/string.cpp
@@ -21,13 +21,14 @@ struct String {
};
// NOTE(bill): used for printf style arguments
#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
- #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
- #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
+#define str_lit(c_str) STR_LIT(c_str)
+
// NOTE(bill): String16 is only used for Windows due to its file directories
struct String16 {
wchar_t *text;