aboutsummaryrefslogtreecommitdiff
path: root/src/check_decl.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-11-02 12:54:23 +0000
committergingerBill <bill@gingerbill.org>2021-11-02 12:54:23 +0000
commitc5cd97dd8968f5f6ad4f130a68008beacda78b64 (patch)
treec62e0b5c96d6abf116b47dceee64901b7b40d2d2 /src/check_decl.cpp
parenta4b68b93f2db127fde34c935e0764deaeb06a518 (diff)
Improve `wasm-import` semantics to allow procedures from different import paths
Diffstat (limited to 'src/check_decl.cpp')
-rw-r--r--src/check_decl.cpp29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index c2d23e70c..127bb67fd 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -594,7 +594,7 @@ bool are_signatures_similar_enough(Type *a_, Type *b_) {
return true;
}
-void init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
+Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
Ast *ident = nullptr;
Entity **foreign_library = nullptr;
@@ -608,7 +608,7 @@ void init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
foreign_library = &e->Variable.foreign_library;
break;
default:
- return;
+ return nullptr;
}
if (ident == nullptr) {
@@ -631,8 +631,10 @@ void init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
*foreign_library = found;
found->flags |= EntityFlag_Used;
add_entity_use(ctx, ident, found);
+ return found;
}
}
+ return nullptr;
}
String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) {
@@ -836,11 +838,27 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
if (e->Procedure.link_name.len > 0) {
name = e->Procedure.link_name;
}
+ Entity *foreign_library = init_entity_foreign_library(ctx, e);
+
+ if (is_arch_wasm()) {
+ String module_name = str_lit("env");
+ if (foreign_library != nullptr) {
+ GB_ASSERT (foreign_library->kind == Entity_LibraryName);
+ if (foreign_library->LibraryName.paths.count != 1) {
+ error(foreign_library->token, "'foreign import' for '%.*s' architecture may only have one path, got %td",
+ LIT(target_arch_names[build_context.metrics.arch]), foreign_library->LibraryName.paths.count);
+ }
+
+ if (foreign_library->LibraryName.paths.count >= 1) {
+ module_name = foreign_library->LibraryName.paths[0];
+ }
+ }
+ name = concatenate3_strings(permanent_allocator(), module_name, WASM_MODULE_NAME_SEPARATOR, name);
+ }
+
e->Procedure.is_foreign = true;
e->Procedure.link_name = name;
- init_entity_foreign_library(ctx, e);
-
mutex_lock(&ctx->info->foreign_mutex);
auto *fp = &ctx->info->foreigns;
@@ -962,6 +980,9 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr,
error(e->token, "A foreign variable declaration cannot have a default value");
}
init_entity_foreign_library(ctx, e);
+ if (is_arch_wasm()) {
+ error(e->token, "A foreign variable declaration are not allowed for the '%.*s' architecture", LIT(target_arch_names[build_context.metrics.arch]));
+ }
}
if (ac.link_name.len > 0) {
e->Variable.link_name = ac.link_name;