<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "m3.h"
#include "m3_api_wasi.h"
#include "m3_api_libc.h"
#include "m3_env.h"

#define FATAL(msg, ...) { printf("Error: [Fatal] " msg "\n", ##__VA_ARGS__); goto _onfatal; }

M3Result repl_load  (IM3Runtime runtime, const char* fn)
{
    M3Result result = c_m3Err_none;

    u8* wasm = NULL;
    u32 fsize = 0;

    FILE* f = fopen (fn, "rb");
    if (!f) {
        return "cannot open file";
    }
    fseek (f, 0, SEEK_END);
    fsize = ftell(f);
    fseek (f, 0, SEEK_SET);

    if (fsize > 10*1024*1024) {
        return "file too big";
    }

    wasm = (u8*) malloc(fsize);
    fread (wasm, 1, fsize, f);
    fclose (f);

    IM3Module module;
    result = m3_ParseModule (runtime->environment, &module, wasm, fsize);
    if (result) return result;

    result = m3_LoadModule (runtime, module);
    if (result) return result;

    return result;
}

M3Result repl_call  (IM3Runtime runtime, const char* name, int argc, const char* argv[])
{
    M3Result result = c_m3Err_none;

    IM3Function func;
    result = m3_FindFunction (&func, runtime, name);
    if (result) return result;

    // TODO
    if (argc) {
        if (!strcmp(name, "main") || !strcmp(name, "_main")) {
            return "passing arguments to libc main() not implemented";
        }
    }

    result = m3_CallWithArgs (func, argc, argv);
    if (result) return result;

    return result;
}

void repl_free(IM3Runtime* runtime)
{
    if (*runtime) {
        m3_FreeRuntime (*runtime);
    }
}

M3Result repl_init(IM3Environment env, IM3Runtime* runtime)
{
    repl_free(runtime);
    *runtime = m3_NewRuntime (env, 64*1024);
    if (*runtime == NULL) {
        return "m3_NewRuntime failed";
    }
    return c_m3Err_none;
}

int split_argv(char *str, const char** argv)
{
    int result = 0;
    char* curr = str;
    int len = 0;
    for (int i = 0; str[i] != '\0'; i++) {
        if (strchr(" \n\r\t", str[i])) {
            if (len) {  // Found space after non-space
                str[i] = '\0';
                argv[result++] = curr;
                len = 0;
            }
        } else {
            if (!len) { // Found non-space after space
                curr = &str[i];
            }
            len++;
        }
    }
    argv[result] = NULL;
    return result;
}

void print_version() {
    puts("wasm3 v0.4.0");
}

void print_usage() {
    puts("Usage:");
    puts("  wasm3 <file> [args...]");
    puts("  wasm3 --func <function> <file> [args...]");
    puts("  wasm3 --repl [file]");
}

#define ARGV_SHIFT()  { i_argc--; i_argv++; }
#define ARGV_SET(x)   { if (i_argc > 0) { x = i_argv[0]; ARGV_SHIFT(); } }

int  main  (int i_argc, const char* i_argv[])
{
    M3Result result = c_m3Err_none;
    
    IM3Environment env = m3_NewEnvironment ();
    IM3Runtime runtime = NULL;
    bool argRepl = false;
    const char* argFile = NULL;
    const char* argFunc = "_start";

//    m3_PrintM3Info ();

    ARGV_SHIFT(); // Skip executable name

    while (i_argc > 0)
    {
        const char* arg = i_argv[0];
        if (arg[0] != '-') break;

        ARGV_SHIFT();
        if (!strcmp("--help", arg) or !strcmp("-h", arg)) {
            print_usage();
            return 0;
        } else if (!strcmp("--version", arg)) {
            print_version();
            return 0;
        } else if (!strcmp("--repl", arg)) {
            argRepl = true;
        } else if (!strcmp("--func", arg) or !strcmp("-f", arg)) {
            ARGV_SET(argFunc);
        }
    }

    if ((argRepl and (i_argc > 1)) or   // repl supports 0 or 1 args
        (not argRepl and (i_argc < 1))  // normal expects at least 1
    ) {
        print_usage();
        return 1;
    }

    ARGV_SET(argFile);

    result = repl_init(env, &runtime);
    if (result) FATAL("repl_init: %s", result);

    if (argFile) {
        result = repl_load(runtime, argFile);
        if (result) FATAL("repl_load: %s", result);

        result = m3_LinkWASI (runtime->modules);
        if (result) FATAL("m3_LinkWASI: %s", result);

        result = m3_LinkLibC (runtime->modules);
        if (result) FATAL("m3_LinkLibC: %s", result);

        if (argFunc and not argRepl) {
            if (!strcmp(argFunc, "_start")) {
                // When passing args to WASI, include wasm filename as argv[0]
                result = repl_call(runtime, argFunc, i_argc+1, i_argv-1);
            } else {
                result = repl_call(runtime, argFunc, i_argc, i_argv);
            }
            if (result) FATAL("repl_call: %s", result);
        }
    }

    while (argRepl)
    {
        char cmd_buff[128] = { 0, };
        const char* argv[32] = { 0, };
        fprintf(stdout, "wasm3> ");
        fflush(stdout);
        if (!fgets(cmd_buff, sizeof(cmd_buff), stdin)) {<commit_msg>Increase command buffer size<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "m3.h"
#include "m3_api_wasi.h"
#include "m3_api_libc.h"
#include "m3_env.h"

#define FATAL(msg, ...) { printf("Error: [Fatal] " msg "\n", ##__VA_ARGS__); goto _onfatal; }

M3Result repl_load  (IM3Runtime runtime, const char* fn)
{
    M3Result result = c_m3Err_none;

    u8* wasm = NULL;
    u32 fsize = 0;

    FILE* f = fopen (fn, "rb");
    if (!f) {
        return "cannot open file";
    }
    fseek (f, 0, SEEK_END);
    fsize = ftell(f);
    fseek (f, 0, SEEK_SET);

    if (fsize > 10*1024*1024) {
        return "file too big";
    }

    wasm = (u8*) malloc(fsize);
    fread (wasm, 1, fsize, f);
    fclose (f);

    IM3Module module;
    result = m3_ParseModule (runtime->environment, &module, wasm, fsize);
    if (result) return result;

    result = m3_LoadModule (runtime, module);
    if (result) return result;

    return result;
}

M3Result repl_call  (IM3Runtime runtime, const char* name, int argc, const char* argv[])
{
    M3Result result = c_m3Err_none;

    IM3Function func;
    result = m3_FindFunction (&func, runtime, name);
    if (result) return result;

    // TODO
    if (argc) {
        if (!strcmp(name, "main") || !strcmp(name, "_main")) {
            return "passing arguments to libc main() not implemented";
        }
    }

    result = m3_CallWithArgs (func, argc, argv);
    if (result) return result;

    return result;
}

void repl_free(IM3Runtime* runtime)
{
    if (*runtime) {
        m3_FreeRuntime (*runtime);
    }
}

M3Result repl_init(IM3Environment env, IM3Runtime* runtime)
{
    repl_free(runtime);
    *runtime = m3_NewRuntime (env, 64*1024);
    if (*runtime == NULL) {
        return "m3_NewRuntime failed";
    }
    return c_m3Err_none;
}

int split_argv(char *str, const char** argv)
{
    int result = 0;
    char* curr = str;
    int len = 0;
    for (int i = 0; str[i] != '\0'; i++) {
        if (strchr(" \n\r\t", str[i])) {
            if (len) {  // Found space after non-space
                str[i] = '\0';
                argv[result++] = curr;
                len = 0;
            }
        } else {
            if (!len) { // Found non-space after space
                curr = &str[i];
            }
            len++;
        }
    }
    argv[result] = NULL;
    return result;
}

void print_version() {
    puts("wasm3 v0.4.0");
}

void print_usage() {
    puts("Usage:");
    puts("  wasm3 <file> [args...]");
    puts("  wasm3 --func <function> <file> [args...]");
    puts("  wasm3 --repl [file]");
}

#define ARGV_SHIFT()  { i_argc--; i_argv++; }
#define ARGV_SET(x)   { if (i_argc > 0) { x = i_argv[0]; ARGV_SHIFT(); } }

int  main  (int i_argc, const char* i_argv[])
{
    M3Result result = c_m3Err_none;
    
    IM3Environment env = m3_NewEnvironment ();
    IM3Runtime runtime = NULL;
    bool argRepl = false;
    const char* argFile = NULL;
    const char* argFunc = "_start";

//    m3_PrintM3Info ();

    ARGV_SHIFT(); // Skip executable name

    while (i_argc > 0)
    {
        const char* arg = i_argv[0];
        if (arg[0] != '-') break;

        ARGV_SHIFT();
        if (!strcmp("--help", arg) or !strcmp("-h", arg)) {
            print_usage();
            return 0;
        } else if (!strcmp("--version", arg)) {
            print_version();
            return 0;
        } else if (!strcmp("--repl", arg)) {
            argRepl = true;
        } else if (!strcmp("--func", arg) or !strcmp("-f", arg)) {
            ARGV_SET(argFunc);
        }
    }

    if ((argRepl and (i_argc > 1)) or   // repl supports 0 or 1 args
        (not argRepl and (i_argc < 1))  // normal expects at least 1
    ) {
        print_usage();
        return 1;
    }

    ARGV_SET(argFile);

    result = repl_init(env, &runtime);
    if (result) FATAL("repl_init: %s", result);

    if (argFile) {
        result = repl_load(runtime, argFile);
        if (result) FATAL("repl_load: %s", result);

        result = m3_LinkWASI (runtime->modules);
        if (result) FATAL("m3_LinkWASI: %s", result);

        result = m3_LinkLibC (runtime->modules);
        if (result) FATAL("m3_LinkLibC: %s", result);

        if (argFunc and not argRepl) {
            if (!strcmp(argFunc, "_start")) {
                // When passing args to WASI, include wasm filename as argv[0]
                result = repl_call(runtime, argFunc, i_argc+1, i_argv-1);
            } else {
                result = repl_call(runtime, argFunc, i_argc, i_argv);
            }
            if (result) FATAL("repl_call: %s", result);
        }
    }

    while (argRepl)
    {
        char cmd_buff[256] = { 0, };
        const char* argv[32] = { 0, };
        fprintf(stdout, "wasm3> ");
        fflush(stdout);
        if (!fgets(cmd_buff, sizeof(cmd_buff), stdin)) {
{'fraction_non_alphanumeric': 0.15279361459521096, 'fraction_numerical': 0.020317197056079612, 'mean_word_length': 2.1284046692607004, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4079148', 'n_tokens_mistral': 3548, 'n_tokens_neox': 3420, 'n_words': 895}