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.
|
- Ability of `vendor-fetch` to register the fetched dependencies in the project file.
|
||||||
- Allow the "self" parameter to be $/# for macro methods.
|
- Allow the "self" parameter to be $/# for macro methods.
|
||||||
- Support compile time slicing of untyped lists.
|
- Support compile time slicing of untyped lists.
|
||||||
|
- Allow specifying an import module using `@wasm` #1305.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Issue where a lambda wasn't correctly registered as external. #1408
|
- Issue where a lambda wasn't correctly registered as external. #1408
|
||||||
|
|||||||
@@ -345,6 +345,7 @@ typedef struct
|
|||||||
const char *deprecated;
|
const char *deprecated;
|
||||||
const char **links;
|
const char **links;
|
||||||
const char *section;
|
const char *section;
|
||||||
|
const char *wasm_module;
|
||||||
SourceSpan overload;
|
SourceSpan overload;
|
||||||
} ResolvedAttrData;
|
} ResolvedAttrData;
|
||||||
|
|
||||||
|
|||||||
@@ -806,6 +806,7 @@ static ResolvedAttrData *copy_attrs_resolved(CopyStruct *c, ResolvedAttrData *da
|
|||||||
.deprecated = data->deprecated,
|
.deprecated = data->deprecated,
|
||||||
.links = data->links,
|
.links = data->links,
|
||||||
.section = data->section,
|
.section = data->section,
|
||||||
|
.wasm_module = data->wasm_module
|
||||||
};
|
};
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1183,6 +1183,10 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl)
|
|||||||
{
|
{
|
||||||
scratch_buffer_set_extern_decl_name(decl, true);
|
scratch_buffer_set_extern_decl_name(decl, true);
|
||||||
llvm_attribute_add_string(c, function, "wasm-import-name", scratch_buffer_to_string(), -1);
|
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))
|
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.
|
// No attribute has more than one argument right now.
|
||||||
unsigned args = vec_size(attr->exprs);
|
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_SEMA_ERROR(attr->exprs[1], "Too many arguments for the attribute.");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
Expr *expr = args ? attr->exprs[0] : NULL;
|
Expr *expr = args ? attr->exprs[0] : NULL;
|
||||||
|
|
||||||
@@ -2554,6 +2553,41 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_
|
|||||||
decl->alignment = (AlignSize)align;
|
decl->alignment = (AlignSize)align;
|
||||||
return true;
|
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:
|
case ATTRIBUTE_EXPORT:
|
||||||
if (context->unit->module->is_generic)
|
if (context->unit->module->is_generic)
|
||||||
{
|
{
|
||||||
@@ -2729,9 +2763,6 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_
|
|||||||
}
|
}
|
||||||
decl->is_weak = true;
|
decl->is_weak = true;
|
||||||
break;
|
break;
|
||||||
case ATTRIBUTE_WASM:
|
|
||||||
decl->is_export = true;
|
|
||||||
break;
|
|
||||||
case ATTRIBUTE_NAKED:
|
case ATTRIBUTE_NAKED:
|
||||||
assert(domain == ATTR_FUNC);
|
assert(domain == ATTR_FUNC);
|
||||||
decl->func_decl.attr_naked = true;
|
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 (!sema_analyse_attributes_inner(context, &data, decl, attrs, domain, NULL, erase_decl)) return false;
|
||||||
if (*erase_decl) return true;
|
if (*erase_decl) return true;
|
||||||
decl->resolved_attributes = 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);
|
ResolvedAttrData *copy = MALLOCS(ResolvedAttrData);
|
||||||
*copy = data;
|
*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