diff --git a/lib/std/core/mem_allocator.c3 b/lib/std/core/mem_allocator.c3
index 2cb10d16b..27b624794 100644
--- a/lib/std/core/mem_allocator.c3
+++ b/lib/std/core/mem_allocator.c3
@@ -178,4 +178,33 @@ fn void ArenaAllocator.init(ArenaAllocator* this, char[] data)
fn void ArenaAllocator.reset(ArenaAllocator* this)
{
this.used = 0;
+}
+
+const usz WASM_BLOCK_SIZE = 65536;
+
+WasmMemory wasm_memory;
+
+struct WasmMemory
+{
+ usz allocation;
+ uptr use;
+}
+
+fn void*! WasmMemory.allocate_block(WasmMemory* this, usz bytes)
+{
+ if (!this.allocation)
+ {
+ this.allocation = $$wasm_memory_size(0) * WASM_BLOCK_SIZE;
+ }
+ isz bytes_required = bytes + this.use - this.allocation;
+ if (bytes_required <= 0)
+ {
+ defer this.use += bytes;
+ return (void*)this.use;
+ }
+ usz blocks_required = (bytes_required + WASM_BLOCK_SIZE + 1) / WASM_BLOCK_SIZE;
+ if (!$$wasm_memory_grow(0, blocks_required)) return AllocationFailure.OUT_OF_MEMORY!;
+ this.allocation = $$wasm_memory_size(0) * WASM_BLOCK_SIZE;
+ defer this.use += bytes;
+ return (void*)this.use;
}
\ No newline at end of file
diff --git a/src/build/build_options.c b/src/build/build_options.c
index b3008ca54..9c5a04b30 100644
--- a/src/build/build_options.c
+++ b/src/build/build_options.c
@@ -83,6 +83,7 @@ static void usage(void)
OUTPUT(" --stdlib
- Use this directory as the C3 standard library path.");
OUTPUT(" --nostdlib - Do not include the standard library.");
OUTPUT(" --nolibc - Do not implicitly link libc nor any associated files.");
+ OUTPUT(" --no-entry - Do not generate (or require) a main function.");
OUTPUT(" --libdir - Add this directory to the C3 library search paths.");
OUTPUT(" --lib - Add this library to the compilation.");
OUTPUT(" --path - Use this as the base directory for the current command.");
@@ -658,6 +659,10 @@ static void parse_option(BuildOptions *options)
options->print_output = true;
return;
}
+ if (match_longopt("no-entry"))
+ {
+ options->no_entry = true;
+ }
if (match_longopt("cc"))
{
if (at_end() || next_is_opt()) error_exit("error: --cc needs a compiler name.");
diff --git a/src/build/build_options.h b/src/build/build_options.h
index ef9773eaf..1a2ee7357 100644
--- a/src/build/build_options.h
+++ b/src/build/build_options.h
@@ -271,6 +271,7 @@ typedef struct BuildOptions_
bool emit_bitcode;
bool test_mode;
bool no_stdlib;
+ bool no_entry;
bool no_libc;
bool force_linker;
bool read_stdin;
@@ -361,6 +362,7 @@ typedef struct
bool testing;
bool read_stdin;
bool print_output;
+ bool no_entry;
int build_threads;
OptimizationLevel optimization_level;
SizeOptimizationLevel size_optimization_level;
diff --git a/src/build/builder.c b/src/build/builder.c
index 22af756a9..8f65a44b2 100644
--- a/src/build/builder.c
+++ b/src/build/builder.c
@@ -220,6 +220,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
}
if (options->no_stdlib) target->no_stdlib = true;
if (options->no_libc) target->no_libc = true;
+ if (options->no_entry) target->no_entry = true;
target->print_output = options->print_output;
target->emit_llvm = options->emit_llvm;
target->build_threads = options->build_threads;
diff --git a/src/build/project.c b/src/build/project.c
index 52050ae08..479cb38f2 100644
--- a/src/build/project.c
+++ b/src/build/project.c
@@ -17,8 +17,10 @@ const char *project_default_keys[] = {
"langrev",
"dependency-search-paths",
"dependencies",
+ "link-args",
"linked-libraries",
"macossdk",
+ "no-entry",
"nolibc",
"nostdlib",
"panicfn",
@@ -50,11 +52,15 @@ const char* project_target_keys[] = {
"c-sources-override",
"debug-info",
"langrev",
+ "nolibc",
+ "no-entry",
"dependency-search-paths-add",
"dependency-search-paths-override",
"dependencies-add",
"dependencies-override",
"linked-libraries",
+ "link-args-override",
+ "link-args-add",
"macossdk",
"nolibc",
"nostdlib",
@@ -245,7 +251,6 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg
target->cflags = cflags_add;
}
}
-
// C source dirs.
target_append_strings(json, type, &target->csource_dirs, "c-sources", "c-sources-override", "c-sources-add", is_default);
@@ -258,6 +263,9 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg
// linker-search-paths libs dir - libraries to add at link time
target_append_strings(json, type, &target->linker_libdirs, "linker-search-paths", "linker-search-paths-override", "linker-search-paths-add", is_default);
+ // link-args - link args to add at link time
+ target_append_strings(json, type, &target->link_args, "link-args", "link-args-override", "link-args-add", is_default);
+
// dependency-search-paths - path to search for libraries
target_append_strings(json, type, &target->libdirs, "dependency-search-paths", "dependency-search-paths-override", "dependency-search-paths-add", is_default);
@@ -309,6 +317,7 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg
int reloc = get_valid_string_setting(json, "reloc", type, reloc_models, 0, 5, "'none', 'pic', 'PIC', 'pie' or 'PIE'.");
if (reloc > -1) target->reloc_model = (RelocModel)reloc;
+
// Cpu
const char *cpu = get_valid_string(json, "cpu", type, false);
if (cpu) target->cpu = cpu;
@@ -348,6 +357,9 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg
// nolibc
target->no_libc = get_valid_bool(json, "nolibc", type, target->no_libc);
+ // no-entry
+ target->no_entry = get_valid_bool(json, "no-entry", type, target->no_entry);
+
// nostdlib
target->no_stdlib = get_valid_bool(json, "nostdlib", type, target->no_stdlib);
diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c
index 556d83fb0..732a861da 100644
--- a/src/compiler/compiler.c
+++ b/src/compiler/compiler.c
@@ -149,11 +149,11 @@ void **tilde_gen(Module** modules, unsigned module_count)
static const char *exe_name(void)
{
- assert(global_context.main);
+ assert(global_context.main || active_target.no_entry);
const char *name;
- if (active_target.name)
+ if (active_target.name || active_target.no_entry)
{
- name = active_target.name;
+ name = active_target.name ? active_target.name : "out";
}
else
{
@@ -350,7 +350,7 @@ void compiler_compile(void)
output_exe = exe_name();
break;
case TARGET_TYPE_EXECUTABLE:
- if (!global_context.main)
+ if (!global_context.main && !active_target.no_entry)
{
puts("No main function was found, compilation only object files are generated.");
}
diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h
index 679bef5e3..4a8ecaf85 100644
--- a/src/compiler/compiler_internal.h
+++ b/src/compiler/compiler_internal.h
@@ -673,6 +673,7 @@ typedef struct Decl_
bool obfuscate : 1;
bool is_dynamic : 1;
bool is_synthetic : 1;
+ bool is_wasm_export : 1;
OperatorOverload operator : 4;
union
{
@@ -2299,6 +2300,7 @@ void codegen_setup_object_names(Module *module, const char **ir_filename, const
void target_setup(BuildTarget *build_target);
int target_alloca_addr_space();
bool os_is_apple(OsType os_type);
+bool arch_is_wasm(ArchType type);
const char *macos_sysroot(void);
MacSDK *macos_sysroot_sdk_information(const char *sdk_path);
diff --git a/src/compiler/enums.h b/src/compiler/enums.h
index 44f873d21..a3b4983ea 100644
--- a/src/compiler/enums.h
+++ b/src/compiler/enums.h
@@ -762,6 +762,7 @@ typedef enum
ATTRIBUTE_BIGENDIAN,
ATTRIBUTE_BUILTIN,
ATTRIBUTE_CDECL,
+ ATTRIBUTE_EXTERN,
ATTRIBUTE_EXTNAME,
ATTRIBUTE_FASTCALL,
ATTRIBUTE_INLINE,
@@ -785,6 +786,7 @@ typedef enum
ATTRIBUTE_UNUSED,
ATTRIBUTE_USED,
ATTRIBUTE_VECCALL,
+ ATTRIBUTE_WASM,
ATTRIBUTE_WEAK,
ATTRIBUTE_NONE,
NUMBER_OF_ATTRIBUTES = ATTRIBUTE_NONE,
@@ -898,6 +900,8 @@ typedef enum
BUILTIN_VECCOMPNE,
BUILTIN_VOLATILE_LOAD,
BUILTIN_VOLATILE_STORE,
+ BUILTIN_WASM_MEMORY_SIZE,
+ BUILTIN_WASM_MEMORY_GROW,
BUILTIN_NONE,
NUMBER_OF_BUILTINS = BUILTIN_NONE,
diff --git a/src/compiler/linker.c b/src/compiler/linker.c
index 2baecff7d..5e0824d65 100644
--- a/src/compiler/linker.c
+++ b/src/compiler/linker.c
@@ -461,9 +461,11 @@ static bool linker_setup(const char ***args_ref, const char **files_to_link, uns
if (use_win)
{
add_arg2("/OUT:", output_file);
+ if (active_target.no_entry) add_arg("/NOENTRY");
}
else
{
+ if (active_target.no_entry) add_arg("--no-entry");
add_arg("-o");
add_arg(output_file);
}
diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c
index 0a3c40ff5..805b3324e 100644
--- a/src/compiler/llvm_codegen.c
+++ b/src/compiler/llvm_codegen.c
@@ -711,6 +711,8 @@ static void llvm_codegen_setup()
intrinsic_id.vector_reduce_and = lookup_intrinsic("llvm.vector.reduce.and");
intrinsic_id.vector_reduce_or = lookup_intrinsic("llvm.vector.reduce.or");
intrinsic_id.vector_reduce_xor = lookup_intrinsic("llvm.vector.reduce.xor");
+ intrinsic_id.wasm_memory_grow = lookup_intrinsic("llvm.wasm.memory.grow");
+ intrinsic_id.wasm_memory_size = lookup_intrinsic("llvm.wasm.memory.size");
attribute_id.align = lookup_attribute("align");
attribute_id.alwaysinline = lookup_attribute("alwaysinline");
diff --git a/src/compiler/llvm_codegen_builtins.c b/src/compiler/llvm_codegen_builtins.c
index f66f18f99..ab9b544ee 100644
--- a/src/compiler/llvm_codegen_builtins.c
+++ b/src/compiler/llvm_codegen_builtins.c
@@ -429,6 +429,23 @@ void llvm_emit_simple_builtin(GenContext *c, BEValue *be_value, Expr *expr, unsi
llvm_value_set(be_value, result, expr->type);
}
+void llvm_emit_builtin_args_types3(GenContext *c, BEValue *be_value, Expr *expr, unsigned intrinsic, Type *type1, Type *type2, Type *type3)
+{
+ Expr **args = expr->call_expr.arguments;
+ unsigned count = vec_size(args);
+ assert(count <= 3);
+ assert(count > 0);
+ LLVMValueRef arg_slots[3];
+ llvm_emit_intrinsic_args(c, args, arg_slots, count);
+ LLVMTypeRef call_type[3];
+ unsigned type_slots = 0;
+ if (type1) call_type[type_slots++] = llvm_get_type(c, type1);
+ if (type2) call_type[type_slots++] = llvm_get_type(c, type2);
+ if (type3) call_type[type_slots++] = llvm_get_type(c, type3);
+ LLVMValueRef result = llvm_emit_call_intrinsic(c, intrinsic, call_type, type_slots, arg_slots, count);
+ llvm_value_set(be_value, result, expr->type);
+}
+
static void llvm_emit_overflow_builtin(GenContext *c, BEValue *be_value, Expr *expr, unsigned intrinsic_signed, unsigned intrinsic_unsigned)
{
Expr **args = expr->call_expr.arguments;
@@ -793,6 +810,24 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
llvm_value_set(result_value, llvm_emit_call_intrinsic(c, intrinsic_id.set_rounding, NULL, 0, arg_slots, 1), type_void);
}
return;
+ case BUILTIN_WASM_MEMORY_GROW:
+ // -1 on non-wasm
+ if (!arch_is_wasm(platform_target.arch))
+ {
+ llvm_value_set(result_value, llvm_const_int(c, expr->type, -1), expr->type);
+ return;
+ }
+ llvm_emit_builtin_args_types3(c, result_value, expr, intrinsic_id.wasm_memory_grow, expr->type, NULL, NULL);
+ return;
+ case BUILTIN_WASM_MEMORY_SIZE:
+ if (!arch_is_wasm(platform_target.arch))
+ {
+ // 0 (no mem) on non-wasm.
+ llvm_value_set(result_value, llvm_const_int(c, expr->type, 0), expr->type);
+ return;
+ }
+ llvm_emit_builtin_args_types3(c, result_value, expr, intrinsic_id.wasm_memory_size, expr->type, NULL, NULL);
+ return;
case BUILTIN_SIN:
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.sin);
return;
diff --git a/src/compiler/llvm_codegen_function.c b/src/compiler/llvm_codegen_function.c
index 675f8f11c..5aa8143c3 100644
--- a/src/compiler/llvm_codegen_function.c
+++ b/src/compiler/llvm_codegen_function.c
@@ -714,6 +714,10 @@ void llvm_emit_function_decl(GenContext *c, Decl *decl)
{
llvm_attribute_add(c, function, attribute_id.noreturn, -1);
}
+ if (decl->is_wasm_export && arch_is_wasm(platform_target.arch))
+ {
+ llvm_attribute_add_string(c, function, "wasm-export-name", decl_get_extname(decl), -1);
+ }
if (decl->alignment != type_abi_alignment(decl->type))
{
llvm_set_alignment(function, decl->alignment);
diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h
index 1c50f2c2c..577df4ef5 100644
--- a/src/compiler/llvm_codegen_internal.h
+++ b/src/compiler/llvm_codegen_internal.h
@@ -198,6 +198,8 @@ typedef struct
unsigned vector_reduce_and;
unsigned vector_reduce_or;
unsigned vector_reduce_xor;
+ unsigned wasm_memory_size;
+ unsigned wasm_memory_grow;
} LLVMIntrinsics;
extern LLVMIntrinsics intrinsic_id;
@@ -221,7 +223,6 @@ typedef struct
unsigned sret; // struct return pointer
unsigned writeonly; // No writes on pointer
unsigned zext; // zero extend
-
} LLVMAttributes;
extern LLVMAttributes attribute_id;
diff --git a/src/compiler/sema_builtins.c b/src/compiler/sema_builtins.c
index df09032aa..98dee7fc5 100644
--- a/src/compiler/sema_builtins.c
+++ b/src/compiler/sema_builtins.c
@@ -456,6 +456,15 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
arg_count)) return false;
rtype = args[0]->type;
break;
+ case BUILTIN_WASM_MEMORY_SIZE:
+ if (!cast_implicit(context, args[0], type_uint)) return false;
+ rtype = type_uptr;
+ break;
+ case BUILTIN_WASM_MEMORY_GROW:
+ if (!cast_implicit(context, args[0], type_uint)) return false;
+ if (!cast_implicit(context, args[1], type_uptr)) return false;
+ rtype = type_iptr;
+ break;
case BUILTIN_PREFETCH:
if (!sema_check_builtin_args(args, (BuiltinArg[]) { BA_POINTER, BA_INTEGER, BA_INTEGER }, arg_count)) return false;
for (unsigned i = 1; i < 3; i++)
@@ -635,6 +644,7 @@ static inline unsigned builtin_expected_args(BuiltinFunction func)
case BUILTIN_REDUCE_MAX:
case BUILTIN_REDUCE_MIN:
case BUILTIN_SET_ROUNDING_MODE:
+ case BUILTIN_WASM_MEMORY_SIZE:
return 1;
case BUILTIN_COPYSIGN:
case BUILTIN_EXACT_ADD:
@@ -658,6 +668,7 @@ static inline unsigned builtin_expected_args(BuiltinFunction func)
case BUILTIN_VECCOMPGE:
case BUILTIN_VECCOMPGT:
case BUILTIN_VECCOMPEQ:
+ case BUILTIN_WASM_MEMORY_GROW:
return 2;
case BUILTIN_FMA:
case BUILTIN_FSHL:
diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c
index e28787286..66a68d248 100644
--- a/src/compiler/sema_decls.c
+++ b/src/compiler/sema_decls.c
@@ -1442,6 +1442,7 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
[ATTRIBUTE_BUILTIN] = ATTR_MACRO | ATTR_FUNC,
[ATTRIBUTE_CDECL] = ATTR_FUNC,
[ATTRIBUTE_EXTNAME] = (AttributeDomain)~(ATTR_CALL | ATTR_BITSTRUCT | ATTR_MACRO | ATTR_XXLIZER),
+ [ATTRIBUTE_EXTERN] = (AttributeDomain)~(ATTR_CALL | ATTR_BITSTRUCT | ATTR_MACRO | ATTR_XXLIZER),
[ATTRIBUTE_FASTCALL] = ATTR_FUNC,
[ATTRIBUTE_INLINE] = ATTR_FUNC | ATTR_CALL,
[ATTRIBUTE_LITTLEENDIAN] = ATTR_BITSTRUCT,
@@ -1465,6 +1466,7 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
[ATTRIBUTE_USED] = (AttributeDomain)~(ATTR_CALL | ATTR_XXLIZER ),
[ATTRIBUTE_VECCALL] = ATTR_FUNC,
[ATTRIBUTE_WEAK] = ATTR_FUNC | ATTR_CONST | ATTR_GLOBAL,
+ [ATTRIBUTE_WASM] = ATTR_FUNC,
};
if ((attribute_domain[type] & domain) != domain)
@@ -1590,10 +1592,11 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
return true;
}
case ATTRIBUTE_SECTION:
+ case ATTRIBUTE_EXTERN:
case ATTRIBUTE_EXTNAME:
if (context->unit->module->is_generic)
{
- sema_error_at(attr->span, "'extname' attributes are not allowed in generic modules.");
+ sema_error_at(attr->span, "'%s' attributes are not allowed in generic modules.", attr->name);
return false;
}
if (!expr)
@@ -1607,15 +1610,19 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
SEMA_ERROR(expr, "Expected a constant string value as argument.");
return false;
}
- if (type == ATTRIBUTE_SECTION)
+ switch (type)
{
- if (!sema_check_section(context, attr)) return false;
- decl->section = expr->const_expr.string.chars;
- }
- else
- {
- decl->has_extname = true;
- decl->extname = expr->const_expr.string.chars;
+ case ATTRIBUTE_SECTION:
+ if (!sema_check_section(context, attr)) return false;
+ decl->section = expr->const_expr.string.chars;
+ break;
+ case ATTRIBUTE_EXTNAME:
+ case ATTRIBUTE_EXTERN:
+ decl->has_extname = true;
+ decl->extname = expr->const_expr.string.chars;
+ break;
+ default:
+ UNREACHABLE;
}
return true;
case ATTRIBUTE_NOINLINE:
@@ -1638,6 +1645,9 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
case ATTRIBUTE_WEAK:
decl->is_weak = true;
break;
+ case ATTRIBUTE_WASM:
+ decl->is_wasm_export = true;
+ break;
case ATTRIBUTE_NAKED:
assert(domain == ATTR_FUNC);
decl->func_decl.attr_naked = true;
@@ -1939,8 +1949,12 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl)
return false;
}
if (active_target.type == TARGET_TYPE_TEST) return true;
-
Decl *function;
+ if (active_target.no_entry)
+ {
+ function = decl;
+ goto REGISTER_MAIN;
+ }
if (!subarray_param && is_int_return)
{
// Int return is pass-through at the moment.
diff --git a/src/compiler/symtab.c b/src/compiler/symtab.c
index 6a89967dc..c8123d22f 100644
--- a/src/compiler/symtab.c
+++ b/src/compiler/symtab.c
@@ -259,6 +259,8 @@ void symtab_init(uint32_t capacity)
builtin_list[BUILTIN_UNREACHABLE] = KW_DEF("unreachable");
builtin_list[BUILTIN_VOLATILE_LOAD] = KW_DEF("volatile_load");
builtin_list[BUILTIN_VOLATILE_STORE] = KW_DEF("volatile_store");
+ builtin_list[BUILTIN_WASM_MEMORY_GROW] = KW_DEF("wasm_memory_grow");
+ builtin_list[BUILTIN_WASM_MEMORY_SIZE] = KW_DEF("wasm_memory_size");
for (unsigned i = 0; i < NUMBER_OF_BUILTINS; i++)
{
@@ -289,6 +291,7 @@ void symtab_init(uint32_t capacity)
attribute_list[ATTRIBUTE_BIGENDIAN] = KW_DEF("@bigendian");
attribute_list[ATTRIBUTE_BUILTIN] = KW_DEF("@builtin");
attribute_list[ATTRIBUTE_CDECL] = KW_DEF("@cdecl");
+ attribute_list[ATTRIBUTE_EXTERN] = KW_DEF("@extern");
attribute_list[ATTRIBUTE_EXTNAME] = KW_DEF("@extname");
attribute_list[ATTRIBUTE_FASTCALL] = KW_DEF("@fastcall");
attribute_list[ATTRIBUTE_INLINE] = KW_DEF("@inline");
@@ -312,6 +315,7 @@ void symtab_init(uint32_t capacity)
attribute_list[ATTRIBUTE_UNUSED] = KW_DEF("@unused");
attribute_list[ATTRIBUTE_USED] = KW_DEF("@used");
attribute_list[ATTRIBUTE_VECCALL] = KW_DEF("@veccall");
+ attribute_list[ATTRIBUTE_WASM] = KW_DEF("@wasm");
attribute_list[ATTRIBUTE_WEAK] = KW_DEF("@weak");
for (unsigned i = 0; i < NUMBER_OF_ATTRIBUTES; i++)
diff --git a/src/compiler/target.c b/src/compiler/target.c
index b3cab3610..8ad51ab43 100644
--- a/src/compiler/target.c
+++ b/src/compiler/target.c
@@ -207,6 +207,11 @@ bool os_is_apple(OsType os_type)
os_type == OS_TYPE_MACOSX || os_type == OS_TYPE_IOS;
}
+bool arch_is_wasm(ArchType type)
+{
+ return type == ARCH_TYPE_WASM32 || type == ARCH_TYPE_WASM64;
+}
+
static AlignSize os_arch_max_alignment_of_vector(OsType os, ArchType arch, EnvironmentType type, ARMVariant variant)
{
switch (arch)
@@ -903,7 +908,7 @@ static ObjectFormatType object_format_from_os(OsType os, ArchType arch_type)
return OBJ_FORMAT_UNSUPPORTED;
case OS_TYPE_UNKNOWN:
case OS_TYPE_NONE:
- if (arch_type == ARCH_TYPE_WASM64 || arch_type == ARCH_TYPE_WASM32) return OBJ_FORMAT_WASM;
+ if (arch_is_wasm(arch_type)) return OBJ_FORMAT_WASM;
FALLTHROUGH;
case OS_TYPE_LINUX:
case OS_TYPE_NETBSD:
@@ -927,8 +932,9 @@ static unsigned os_target_supports_int128(OsType os, ArchType arch)
switch (arch)
{
case ARCH_TYPE_RISCV64:
- return true;
case ARCH_TYPE_AARCH64:
+ case ARCH_TYPE_WASM32:
+ case ARCH_TYPE_WASM64:
return true;
case ARCH_TYPE_PPC:
default:
diff --git a/src/version.h b/src/version.h
index a80960859..dce0782ff 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define COMPILER_VERSION "0.4.22"
\ No newline at end of file
+#define COMPILER_VERSION "0.4.23"
\ No newline at end of file