Skip to content

Commit

Permalink
Get command line options only if necessary
Browse files Browse the repository at this point in the history
Rename `main` function according to argument count:

  * 0: `__main_void`
  * 2: `__main_argc_argv`

The entry point (`_start` function) calls `__main_void` function.
If user defines `main` as zero arguments, then it is called.
If user defines `main` as two arguments,
`__main_void` defined in library code is called
then user defined `main` function is called.

# Conflicts:
#	src/wcc/traverse.c
  • Loading branch information
tyfkda committed Oct 28, 2024
1 parent c4c31a6 commit 51cc820
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 40 deletions.
24 changes: 24 additions & 0 deletions libsrc/_wasm/crt0/__main_void.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "alloca.h"

#include "../wasi.h"

extern int __main_argc_argv(int, char**);

__attribute__((weak))
int __main_void(void) {
char **argv;
int argc, len;
int r = args_sizes_get(&argc, &len);
if (r == 0) {
argv = alloca(sizeof(char*) * (argc + 1) + len);
char *str = ((char*)argv) + sizeof(char*) * (argc + 1);
args_get(argv, str);
} else { // Ignore error.
argc = 1;
argv = alloca(sizeof(char*) * (argc + 1));
argv[0] = "*";
}
argv[argc] = NULL;

return __main_argc_argv(argc, argv);
}
19 changes: 2 additions & 17 deletions libsrc/_wasm/crt0/_start.c
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
#include "alloca.h" // alloca
#include "stdlib.h" // exit

#include "../wasi.h"

extern void __wasm_call_ctors(void);

void _start(void) {
#define main __main_argc_argv
extern int main(int, char**);
char **argv;
int argc, len;
int r = args_sizes_get(&argc, &len);
if (r == 0) {
argv = alloca(sizeof(char*) * (argc + 1) + len);
char *str = ((char*)argv) + sizeof(char*) * (argc + 1);
args_get(argv, str);
} else { // Ignore error.
argc = 1;
argv = alloca(sizeof(char*) * (argc + 1));
argv[0] = "*";
}
argv[argc] = NULL;
extern int __main_void(void);

__wasm_call_ctors();

int ec = main(argc, argv);
int ec = __main_void();
exit(ec);
#undef main
}
33 changes: 10 additions & 23 deletions src/wcc/traverse.c
Original file line number Diff line number Diff line change
Expand Up @@ -709,36 +709,23 @@ static void modify_func_name(Function *func) {
const Name *newname = NULL;
switch (func->params->len) {
case 0:
{ // Add two parameters.
assert(func->scopes->len > 0);
Scope *scope = func->scopes->data[0];
const Name *name1 = alloc_label();
Type *type1 = &tyInt;
vec_push((Vector*)func->params, scope_add(scope, name1, type1, 0));
vec_push((Vector*)functype->func.params, type1);

Type *type2 = ptrof(ptrof(&tyChar));
const Name *name2 = alloc_label();
vec_push((Vector*)func->params, scope_add(scope, name2, type2, 0));
vec_push((Vector*)functype->func.params, type2);
}
// Fallthrough.
newname = alloc_name("__main_void", NULL, false);
break;
case 2:
{
newname = alloc_name("__main_argc_argv", NULL, false);
VarInfo *vi = scope_find(global_scope, newname, NULL);
if (vi != NULL) {
const Token *token = func->body_block != NULL ? func->body_block->token : NULL;
parse_error(PE_NOFATAL, token, "`%.*s' function already defined", NAMES(newname));
return;
}
}
newname = alloc_name("__main_argc_argv", NULL, false);
break;
default:
error("main function must take no argument or two arguments");
break;
}

VarInfo *vi = scope_find(global_scope, newname, NULL);
if (vi != NULL) {
const Token *token = func->body_block != NULL ? func->body_block->token : NULL;
parse_error(PE_NOFATAL, token, "`%.*s' function already defined", NAMES(newname));
return;
}

// Rename two arguments `main` to `__main_argc_argv`.
VarInfo *org_varinfo = scope_find(global_scope, main_name, NULL);
assert(org_varinfo != NULL);
Expand Down

0 comments on commit 51cc820

Please sign in to comment.