|
|
|
@ -11,6 +11,8 @@
|
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <sys/utsname.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
|
|
|
|
|
#include "wasm3.h"
|
|
|
|
|
#include "m3_env.h"
|
|
|
|
@ -18,56 +20,89 @@
|
|
|
|
|
|
|
|
|
|
#include "fib32.wasm.h"
|
|
|
|
|
|
|
|
|
|
#define FIB_ARG_VALUE "40"
|
|
|
|
|
#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; }
|
|
|
|
|
|
|
|
|
|
uint32_t fib_native(uint32_t n) {
|
|
|
|
|
if (n < 2) return n;
|
|
|
|
|
return fib_native(n - 1) + fib_native(n - 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// same function uses on fib.wasm so we preserve is as is.
|
|
|
|
|
// Note: for prevent precalculation FIB_ARG_VALUE on compile time we need disable inlining
|
|
|
|
|
__attribute__((noinline))
|
|
|
|
|
int parseInt(char* str) {
|
|
|
|
|
int res = 0;
|
|
|
|
|
for (int i = 0; str[i] != '\0'; ++i) {
|
|
|
|
|
res = res * 10 + str[i] - '0';
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void run_native() {
|
|
|
|
|
printf("Running fib(" FIB_ARG_VALUE ") on Native C...\n");
|
|
|
|
|
|
|
|
|
|
clock_t start = clock();
|
|
|
|
|
uint32_t result = fib_native(parseInt(FIB_ARG_VALUE));
|
|
|
|
|
clock_t end = clock();
|
|
|
|
|
|
|
|
|
|
printf("Result: %u\n", result);
|
|
|
|
|
printf("Elapsed: %ld ms\n", (end - start) * 1000 / CLOCKS_PER_SEC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void run_wasm()
|
|
|
|
|
{
|
|
|
|
|
M3Result result = m3Err_none;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t* wasm = (uint8_t*)fib32_wasm;
|
|
|
|
|
uint32_t fsize = fib32_wasm_len-1;
|
|
|
|
|
|
|
|
|
|
uint32_t fsize = fib32_wasm_len - 1;
|
|
|
|
|
|
|
|
|
|
printf("Loading WebAssembly...\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IM3Environment env = m3_NewEnvironment ();
|
|
|
|
|
if (!env) FATAL("m3_NewEnvironment failed");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IM3Runtime runtime = m3_NewRuntime (env, 8192, NULL);
|
|
|
|
|
if (!runtime) FATAL("m3_NewRuntime failed");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IM3Module module;
|
|
|
|
|
result = m3_ParseModule (env, &module, wasm, fsize);
|
|
|
|
|
if (result) FATAL("m3_ParseModule: %s", result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result = m3_LoadModule (runtime, module);
|
|
|
|
|
if (result) FATAL("m3_LoadModule: %s", result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IM3Function f;
|
|
|
|
|
result = m3_FindFunction (&f, runtime, "fib");
|
|
|
|
|
if (result) FATAL("m3_FindFunction: %s", result);
|
|
|
|
|
|
|
|
|
|
printf("Running...\n");
|
|
|
|
|
|
|
|
|
|
const char* i_argv[2] = { "40", NULL };
|
|
|
|
|
|
|
|
|
|
printf("Running fib(" FIB_ARG_VALUE ") on WebAssembly...\n");
|
|
|
|
|
|
|
|
|
|
const char* i_argv[2] = { FIB_ARG_VALUE, NULL };
|
|
|
|
|
|
|
|
|
|
clock_t start = clock();
|
|
|
|
|
result = m3_CallWithArgs (f, 1, i_argv);
|
|
|
|
|
|
|
|
|
|
clock_t end = clock();
|
|
|
|
|
|
|
|
|
|
if (result) FATAL("m3_CallWithArgs: %s", result);
|
|
|
|
|
|
|
|
|
|
long value = *(uint64_t*)(runtime->stack);
|
|
|
|
|
printf("Result: %ld\n", value);
|
|
|
|
|
printf("Elapsed: %ld ms\n\n", (end - start) * 1000 / CLOCKS_PER_SEC);
|
|
|
|
|
|
|
|
|
|
// uint64_t value = *(uint64_t*)(runtime->stack);
|
|
|
|
|
// printf("Result: %llu\n", value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void* runMain(void* ctx)
|
|
|
|
|
{
|
|
|
|
|
struct utsname systemInfo;
|
|
|
|
|
uname(&systemInfo);
|
|
|
|
|
|
|
|
|
|
printf("Wasm3 v" M3_VERSION " on iOS (" M3_ARCH ")\n");
|
|
|
|
|
printf("Build " __DATE__ " " __TIME__ "\n");
|
|
|
|
|
|
|
|
|
|
clock_t start = clock();
|
|
|
|
|
printf("Device: %s\n\n", systemInfo.machine);
|
|
|
|
|
|
|
|
|
|
run_wasm();
|
|
|
|
|
clock_t end = clock();
|
|
|
|
|
|
|
|
|
|
printf("Elapsed: %ld ms\n", (end - start)*1000 / CLOCKS_PER_SEC);
|
|
|
|
|
|
|
|
|
|
run_native();
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -89,16 +124,17 @@ static int stdout_redirect(void* prefix, const char* buffer, int size)
|
|
|
|
|
void redirect_output(print_cbk_t f)
|
|
|
|
|
{
|
|
|
|
|
gPrintFunc = f;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setvbuf(stdout, 0, _IOLBF, 0); // stdout: line-buffered
|
|
|
|
|
setvbuf(stderr, 0, _IONBF, 0); // stderr: unbuffered
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stdout->_write = stdout_redirect;
|
|
|
|
|
stderr->_write = stdout_redirect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int run_app()
|
|
|
|
|
{
|
|
|
|
|
mlockall(MCL_CURRENT | MCL_FUTURE);
|
|
|
|
|
static pthread_t mainThread;
|
|
|
|
|
pthread_attr_t threadAttr;
|
|
|
|
|
pthread_attr_init(&threadAttr);
|
|
|
|
|