Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't #include inside extern "C" blocks. #2108

Merged
merged 6 commits into from
Feb 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions lib/cli/src/c_gen/object_file_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ pub fn generate_header_file(
) -> String {
let mut c_statements = vec![];
c_statements.push(CStatement::LiteralConstant {
value: "#include <stdlib.h>\n\n".to_string(),
value: "#include <stdlib.h>\n#include <string.h>\n\n".to_string(),
});
c_statements.push(CStatement::LiteralConstant {
value: "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n".to_string(),
});
c_statements.push(CStatement::Declaration {
name: "module_bytes_len".to_string(),
Expand Down Expand Up @@ -285,11 +288,9 @@ pub fn generate_header_file(
value: HELPER_FUNCTIONS.to_string(),
});

let inner_c = generate_c(&c_statements);
c_statements.push(CStatement::LiteralConstant {
value: "\n#ifdef __cplusplus\n}\n#endif\n\n".to_string(),
});
Comment on lines +291 to +293
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember much about the abstractions here but it might be nice to have the CPlusPlus guard be a thing that can work on nested data / trees so we don't have to remember to close it ourselves.

Don't let that block this PR though


// we wrap the inner C to work with C++ too
format!(
"#ifdef __cplusplus\nextern \"C\" {{\n#endif\n\n{}\n\n#ifdef __cplusplus\n}}\n#endif\n",
inner_c
)
generate_c(&c_statements)
}
133 changes: 57 additions & 76 deletions lib/cli/src/commands/wasmer_create_exe_main.c
Original file line number Diff line number Diff line change
@@ -1,63 +1,42 @@
#ifdef __cplusplus
extern "C" {
#endif

#include "wasmer_wasm.h"
#include "wasm.h"
#include "my_wasm.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define own

// TODO: make this define templated so that the Rust code can toggle it on/off
#define WASI

#ifdef __cplusplus
}
#endif

void print_wasmer_error()
{
static void print_wasmer_error() {
int error_len = wasmer_last_error_length();
printf("Error len: `%d`\n", error_len);
char* error_str = (char*) malloc(error_len);
char *error_str = (char *)malloc(error_len);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will never believe that char *name is more readable or accurate than char* name 😆

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

char x, *y, f() is a char, a pointer-to-char and a function that returns a char. What a language! 😆

wasmer_last_error_message(error_str, error_len);
printf("%s\n", error_str);
free(error_str);
}

#ifdef WASI
int find_colon(char* string) {
int colon_location = 0;
for (int j = 0; j < strlen(string); ++j) {
if (string[j] == ':') {
colon_location = j;
break;
}
}
return colon_location;
}

void pass_mapdir_arg(wasi_config_t* wasi_config, char* mapdir) {
int colon_location = find_colon(mapdir);
static void pass_mapdir_arg(wasi_config_t *wasi_config, char *mapdir) {
int colon_location = strchr(mapdir, ':') - mapdir;
if (colon_location == 0) {
// error malformed argument
fprintf(stderr, "Expected mapdir argument of the form alias:directory\n");
exit(-1);
}

char *alias = (char *)malloc(colon_location + 1);
memcpy(alias, mapdir, colon_location);
alias[colon_location] = '\0';

int dir_len = strlen(mapdir) - colon_location;
char* alias = (char*)malloc(colon_location + 1);
char* dir = (char*)malloc(dir_len + 1);
int j = 0;
for (j = 0; j < colon_location; ++j) {
alias[j] = mapdir[j];
}
alias[j] = 0;
for (j = 0; j < dir_len; ++j) {
dir[j] = mapdir[j + colon_location + 1];
}
dir[j] = 0;
char *dir = (char *)malloc(dir_len + 1);
memcpy(dir, &mapdir[colon_location + 1], dir_len);
dir[dir_len] = '\0';

wasi_config_mapdir(wasi_config, alias, dir);
free(alias);
Expand All @@ -66,82 +45,84 @@ void pass_mapdir_arg(wasi_config_t* wasi_config, char* mapdir) {

// We try to parse out `--dir` and `--mapdir` ahead of time and process those
// specially. All other arguments are passed to the guest program.
void handle_arguments(wasi_config_t* wasi_config, int argc, char* argv[]) {
static void handle_arguments(wasi_config_t *wasi_config, int argc,
char *argv[]) {
for (int i = 1; i < argc; ++i) {
// We probably want special args like `--dir` and `--mapdir` to not be passed directly
// We probably want special args like `--dir` and `--mapdir` to not be
// passed directly
if (strcmp(argv[i], "--dir") == 0) {
// next arg is a preopen directory
if ((i + 1) < argc ) {
if ((i + 1) < argc) {
i++;
wasi_config_preopen_dir(wasi_config, argv[i]);
} else {
fprintf(stderr, "--dir expects a following argument specifying which directory to preopen\n");
fprintf(stderr, "--dir expects a following argument specifying which "
"directory to preopen\n");
exit(-1);
}
}
else if (strcmp(argv[i], "--mapdir") == 0) {
} else if (strcmp(argv[i], "--mapdir") == 0) {
// next arg is a mapdir
if ((i + 1) < argc ) {
if ((i + 1) < argc) {
i++;
pass_mapdir_arg(wasi_config, argv[i]);
} else {
fprintf(stderr, "--mapdir expects a following argument specifying which directory to preopen in the form alias:directory\n");
fprintf(stderr,
"--mapdir expects a following argument specifying which "
"directory to preopen in the form alias:directory\n");
exit(-1);
}
}
else if (strncmp(argv[i], "--dir=", strlen("--dir=")) == 0 ) {
} else if (strncmp(argv[i], "--dir=", strlen("--dir=")) == 0) {
// this arg is a preopen dir
char* dir = argv[i] + strlen("--dir=");
char *dir = argv[i] + strlen("--dir=");
wasi_config_preopen_dir(wasi_config, dir);
}
else if (strncmp(argv[i], "--mapdir=", strlen("--mapdir=")) == 0 ) {
} else if (strncmp(argv[i], "--mapdir=", strlen("--mapdir=")) == 0) {
// this arg is a mapdir
char* mapdir = argv[i] + strlen("--mapdir=");
char *mapdir = argv[i] + strlen("--mapdir=");
pass_mapdir_arg(wasi_config, mapdir);
}
else {
} else {
// guest argument
wasi_config_arg(wasi_config, argv[i]);
}
}
}
#endif

int main(int argc, char* argv[]) {
wasm_config_t* config = wasm_config_new();
int main(int argc, char *argv[]) {
wasm_config_t *config = wasm_config_new();
wasm_config_set_engine(config, OBJECT_FILE);
wasm_engine_t* engine = wasm_engine_new_with_config(config);
wasm_store_t* store = wasm_store_new(engine);
wasm_module_t* module = wasmer_object_file_engine_new(store, argv[0]);
if (! module) {
wasm_engine_t *engine = wasm_engine_new_with_config(config);
wasm_store_t *store = wasm_store_new(engine);

wasm_module_t *module = wasmer_object_file_engine_new(store, argv[0]);
if (!module) {
fprintf(stderr, "Failed to create module\n");
print_wasmer_error();
return -1;
}

// We have now finished the memory buffer book keeping and we have a valid Module.

#ifdef WASI
wasi_config_t* wasi_config = wasi_config_new(argv[0]);
// We have now finished the memory buffer book keeping and we have a valid
// Module.

#ifdef WASI
wasi_config_t *wasi_config = wasi_config_new(argv[0]);
handle_arguments(wasi_config, argc, argv);

wasi_env_t* wasi_env = wasi_env_new(wasi_config);
wasi_env_t *wasi_env = wasi_env_new(wasi_config);
if (!wasi_env) {
fprintf(stderr, "Error building WASI env!\n");
print_wasmer_error();
return 1;
}
#endif
#endif

wasm_importtype_vec_t import_types;
wasm_module_imports(module, &import_types);

wasm_extern_vec_t imports;
wasm_extern_vec_new_uninitialized(&imports, import_types.size);
wasm_importtype_vec_delete(&import_types);
#ifdef WASI

#ifdef WASI
bool get_imports_result = wasi_get_imports(store, module, wasi_env, &imports);
wasi_env_delete(wasi_env);

Expand All @@ -151,18 +132,18 @@ int main(int argc, char* argv[]) {

return 1;
}
#endif
wasm_instance_t* instance = wasm_instance_new(store, module, &imports, NULL);
#endif

wasm_instance_t *instance = wasm_instance_new(store, module, &imports, NULL);

if (!instance) {
fprintf(stderr, "Failed to create instance\n");
print_wasmer_error();
return -1;
}
#ifdef WASI
own wasm_func_t* start_function = wasi_get_start_function(instance);

#ifdef WASI
own wasm_func_t *start_function = wasi_get_start_function(instance);
if (!start_function) {
fprintf(stderr, "`_start` function not found\n");
print_wasmer_error();
Expand All @@ -171,15 +152,15 @@ int main(int argc, char* argv[]) {

wasm_val_vec_t args = WASM_EMPTY_VEC;
wasm_val_vec_t results = WASM_EMPTY_VEC;
own wasm_trap_t* trap = wasm_func_call(start_function, &args, &results);
own wasm_trap_t *trap = wasm_func_call(start_function, &args, &results);
if (trap) {
fprintf(stderr, "Trap is not NULL: TODO:\n");
return -1;
}
#endif
#endif

// TODO: handle non-WASI start (maybe with invoke?)

wasm_instance_delete(instance);
wasm_module_delete(module);
wasm_store_delete(store);
Expand Down
13 changes: 3 additions & 10 deletions lib/engine-object-file/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ Target: x86_64-apple-darwin
Now lets create a program to link with this object file.

```C
#ifdef __cplusplus
extern "C" {
#endif

#include "wasmer_wasm.h"
#include "wasm.h"
#include "my_wasm.h"
Expand All @@ -38,17 +34,14 @@ extern "C" {

#define own

#ifdef __cplusplus
}
#endif

void print_wasmer_error()
static void print_wasmer_error()
{
int error_len = wasmer_last_error_length();
printf("Error len: `%d`\n", error_len);
char* error_str = (char*) malloc(error_len);
wasmer_last_error_message(error_str, error_len);
printf("Error str: `%s`\n", error_str);
free(error_str);
}

int main() {
Expand All @@ -59,7 +52,7 @@ int main() {
wasm_store_t* store = wasm_store_new(engine);

wasm_module_t* module = wasmer_object_file_engine_new(store, "qjs.wasm");
if (! module) {
if (!module) {
printf("Failed to create module\n");
print_wasmer_error();
return -1;
Expand Down
Loading