Allow specifying an import module using @wasm #1305.

This commit is contained in:
Christoffer Lerno
2024-09-24 21:31:48 +02:00
parent d067a31ce6
commit a258f2084f
8 changed files with 84 additions and 7 deletions

View File

@@ -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

View File

@@ -345,6 +345,7 @@ typedef struct
const char *deprecated;
const char **links;
const char *section;
const char *wasm_module;
SourceSpan overload;
} ResolvedAttrData;

View File

@@ -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;
}

View File

@@ -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))
{

View File

@@ -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;

View 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
}

View 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" }

View 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