mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Allow specifying an import module using @wasm #1305.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
- Ability of `vendor-fetch` to register the fetched dependencies in the project file.
|
||||
- Allow the "self" parameter to be $/# for macro methods.
|
||||
- Support compile time slicing of untyped lists.
|
||||
- Allow specifying an import module using `@wasm` #1305.
|
||||
|
||||
### Fixes
|
||||
- Issue where a lambda wasn't correctly registered as external. #1408
|
||||
|
||||
@@ -345,6 +345,7 @@ typedef struct
|
||||
const char *deprecated;
|
||||
const char **links;
|
||||
const char *section;
|
||||
const char *wasm_module;
|
||||
SourceSpan overload;
|
||||
} ResolvedAttrData;
|
||||
|
||||
|
||||
@@ -806,6 +806,7 @@ static ResolvedAttrData *copy_attrs_resolved(CopyStruct *c, ResolvedAttrData *da
|
||||
.deprecated = data->deprecated,
|
||||
.links = data->links,
|
||||
.section = data->section,
|
||||
.wasm_module = data->wasm_module
|
||||
};
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -1183,6 +1183,10 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl)
|
||||
{
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
llvm_attribute_add_string(c, function, "wasm-import-name", scratch_buffer_to_string(), -1);
|
||||
if (decl->attrs_resolved && decl->attrs_resolved->wasm_module)
|
||||
{
|
||||
llvm_attribute_add_string(c, function, "wasm-import-module", decl->attrs_resolved->wasm_module, -1);
|
||||
}
|
||||
}
|
||||
if (decl->alignment != type_abi_alignment(decl->type))
|
||||
{
|
||||
|
||||
@@ -2419,10 +2419,9 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_
|
||||
|
||||
// No attribute has more than one argument right now.
|
||||
unsigned args = vec_size(attr->exprs);
|
||||
if (args > 1 && type != ATTRIBUTE_LINK && type != ATTRIBUTE_TAG)
|
||||
if (args > 1 && type != ATTRIBUTE_LINK && type != ATTRIBUTE_TAG && type != ATTRIBUTE_WASM)
|
||||
{
|
||||
SEMA_ERROR(attr->exprs[1], "Too many arguments for the attribute.");
|
||||
return false;
|
||||
RETURN_SEMA_ERROR(attr->exprs[1], "Too many arguments for the attribute.");
|
||||
}
|
||||
Expr *expr = args ? attr->exprs[0] : NULL;
|
||||
|
||||
@@ -2554,6 +2553,41 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_
|
||||
decl->alignment = (AlignSize)align;
|
||||
return true;
|
||||
}
|
||||
case ATTRIBUTE_WASM:
|
||||
if (args > 2) RETURN_SEMA_ERROR(attr->exprs[2], "Too many arguments to '@wasm', expected 0, 1 or 2 arguments");
|
||||
decl->is_export = true;
|
||||
if (context->unit->module->is_generic)
|
||||
{
|
||||
RETURN_SEMA_ERROR(attr, "'@wasm' is not allowed in generic modules.");
|
||||
}
|
||||
if (args == 0) return true;
|
||||
if (decl->has_extname)
|
||||
{
|
||||
RETURN_SEMA_ERROR(expr, "An external name is already defined, please use '@wasm` without an argument.");
|
||||
}
|
||||
if (args == 2)
|
||||
{
|
||||
if (!decl->is_extern)
|
||||
{
|
||||
RETURN_SEMA_ERROR(expr, "Specifying a wasm import module name is only valid for extern declarations.");
|
||||
}
|
||||
Expr *module = expr;
|
||||
expr = attr->exprs[1];
|
||||
if (!sema_analyse_expr(context, module)) return false;
|
||||
if (!expr_is_const_string(module))
|
||||
{
|
||||
RETURN_SEMA_ERROR(module, "Expected a constant string value as argument.");
|
||||
}
|
||||
attr_data->wasm_module = module->const_expr.bytes.ptr;
|
||||
if (!sema_analyse_expr(context, expr)) return false;
|
||||
if (!expr_is_const_string(expr))
|
||||
{
|
||||
RETURN_SEMA_ERROR(expr, "Expected a constant string value as argument.");
|
||||
}
|
||||
decl->extname = expr->const_expr.bytes.ptr;
|
||||
decl->has_extname = true;
|
||||
}
|
||||
return true;
|
||||
case ATTRIBUTE_EXPORT:
|
||||
if (context->unit->module->is_generic)
|
||||
{
|
||||
@@ -2729,9 +2763,6 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_
|
||||
}
|
||||
decl->is_weak = true;
|
||||
break;
|
||||
case ATTRIBUTE_WASM:
|
||||
decl->is_export = true;
|
||||
break;
|
||||
case ATTRIBUTE_NAKED:
|
||||
assert(domain == ATTR_FUNC);
|
||||
decl->func_decl.attr_naked = true;
|
||||
@@ -2915,7 +2946,7 @@ static bool sema_analyse_attributes(SemaContext *context, Decl *decl, Attr **att
|
||||
if (!sema_analyse_attributes_inner(context, &data, decl, attrs, domain, NULL, erase_decl)) return false;
|
||||
if (*erase_decl) return true;
|
||||
decl->resolved_attributes = true;
|
||||
if (data.tags || data.deprecated || data.links || data.section || data.overload.row)
|
||||
if (data.tags || data.deprecated || data.links || data.section || data.overload.row || data.wasm_module )
|
||||
{
|
||||
ResolvedAttrData *copy = MALLOCS(ResolvedAttrData);
|
||||
*copy = data;
|
||||
|
||||
26
test/test_suite/attributes/attributes_repeat_param.c3t
Normal file
26
test/test_suite/attributes/attributes_repeat_param.c3t
Normal file
@@ -0,0 +1,26 @@
|
||||
// #target: macos-aarch64
|
||||
module test;
|
||||
|
||||
def @Test(x) = { @extern("Foo" +++ x) };
|
||||
|
||||
fn void hello_world() @Test("Megaman")
|
||||
{}
|
||||
|
||||
fn void ello_world() @Test("Pegasus")
|
||||
{}
|
||||
|
||||
fn int main()
|
||||
{
|
||||
hello_world();
|
||||
ello_world();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
call void @FooMegaman()
|
||||
call void @FooPegasus()
|
||||
ret i32 0
|
||||
}
|
||||
8
test/test_suite/attributes/wasm_import.c3t
Normal file
8
test/test_suite/attributes/wasm_import.c3t
Normal file
@@ -0,0 +1,8 @@
|
||||
// #target: wasm32
|
||||
module test;
|
||||
extern fn void test() @wasm("hello", "world");
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
declare void @world() #0
|
||||
attributes #0 = { nounwind uwtable "no-trapping-math"="true" "stack-protector-buffer-size"="8" "wasm-export-name"="world" "wasm-import-module"="hello" "wasm-import-name"="world" }
|
||||
5
test/test_suite/attributes/wasm_module.c3
Normal file
5
test/test_suite/attributes/wasm_module.c3
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
fn void test() @wasm("hello", "world") { } // #error: Specifying a wasm import module
|
||||
extern fn void test2() @wasm("a", "b", "c"); // #error: Too many arguments to
|
||||
extern fn void test3() @extern("hello") @wasm("a"); // #error: An external name
|
||||
extern fn void test4() @extern("hello") @wasm("a", "b"); // #error: An external name
|
||||
Reference in New Issue
Block a user