|
|
|
@ -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,14 +20,42 @@
|
|
|
|
|
|
|
|
|
|
#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");
|
|
|
|
|
|
|
|
|
@ -46,27 +76,32 @@ void run_wasm()
|
|
|
|
|
result = m3_FindFunction (&f, runtime, "fib");
|
|
|
|
|
if (result) FATAL("m3_FindFunction: %s", result);
|
|
|
|
|
|
|
|
|
|
printf("Running...\n");
|
|
|
|
|
printf("Running fib(" FIB_ARG_VALUE ") on WebAssembly...\n");
|
|
|
|
|
|
|
|
|
|
const char* i_argv[2] = { FIB_ARG_VALUE, NULL };
|
|
|
|
|
|
|
|
|
|
const char* i_argv[2] = { "40", NULL };
|
|
|
|
|
clock_t start = clock();
|
|
|
|
|
result = m3_CallWithArgs (f, 1, i_argv);
|
|
|
|
|
clock_t end = clock();
|
|
|
|
|
|
|
|
|
|
if (result) FATAL("m3_CallWithArgs: %s", result);
|
|
|
|
|
printf("Elapsed: %ld ms\n\n", (end - start) * 1000 / CLOCKS_PER_SEC);
|
|
|
|
|
|
|
|
|
|
long value = *(uint64_t*)(runtime->stack);
|
|
|
|
|
printf("Result: %ld\n", value);
|
|
|
|
|
// 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");
|
|
|
|
|
printf("Device: %s\n\n", systemInfo.machine);
|
|
|
|
|
|
|
|
|
|
clock_t start = clock();
|
|
|
|
|
run_wasm();
|
|
|
|
|
clock_t end = clock();
|
|
|
|
|
|
|
|
|
|
printf("Elapsed: %ld ms\n", (end - start)*1000 / CLOCKS_PER_SEC);
|
|
|
|
|
run_native();
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -99,6 +134,7 @@ void redirect_output(print_cbk_t f)
|
|
|
|
|
|
|
|
|
|
int run_app()
|
|
|
|
|
{
|
|
|
|
|
mlockall(MCL_CURRENT | MCL_FUTURE);
|
|
|
|
|
static pthread_t mainThread;
|
|
|
|
|
pthread_attr_t threadAttr;
|
|
|
|
|
pthread_attr_init(&threadAttr);
|
|
|
|
|