Newer
Older

Mohammad Mahhouk
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include "wasm_export.h"
void my_printf(wasm_exec_env_t exec_env, char *text)
{
printf(text);
}
void my_nprintf(wasm_exec_env_t exec_env, char *text, size_t len)
{
printf("message: '%.*s'\n", len, text);
}
void hello_world(wasm_exec_env_t exec_env)
{
printf("simple hello world is here \n");
}
char *read_wasm_binary_to_buffer(char *path, uint32_t *size)
{
FILE *fd = fopen(path, "rb");
if(!fd)
{
perror("fopen failed!\n");
return NULL;
}
if (fseek(fd, 0, SEEK_END) != 0)
{
perror("fseek failed\n");
return NULL;
}
long fsize = ftell(fd);
if(fseek(fd, 0, SEEK_SET) != 0) // rewind(fd); can be used here too
{
perror("fseek failed\n");
return NULL;
}
char *buffer = malloc(fsize + 1);
if (!buffer)
{
perror("malloc for file buffer failed!\n");
return NULL;
}
size_t read_bytes = fread(buffer, 1, fsize, fd);
if(read_bytes != fsize)
{
fprintf(stderr, "file read didnt read the whole file size and returned only %zu instead of %zu \n", read_bytes, fsize);
exit(EXIT_FAILURE);
}
fclose(fd);
*size = fsize + 1;
buffer[fsize] = 0;
return buffer;
}
int main(int argc, char *argv[])
{
static NativeSymbol native_symbols[] =
{
{
"my_printf", // the name of WASM function name
my_printf, // the native function pointer
"($)" // the function prototype signature
},
{
"my_nprintf", // the name of WASM function name
my_nprintf, // the native function pointer
"(*~)" // the function prototype signature
},
{
"hello_world", // the name of WASM function name
hello_world, // the native function pointer
"()" // the function prototype signature
}
};
char *buffer, error_buf[128];
wasm_module_t module;
wasm_module_inst_t module_inst;
wasm_function_inst_t func;
wasm_exec_env_t exec_env;
uint32_t size, stack_size = 8092, heap_size = 8092;
/* initialize the wasm runtime by default configurations */
if(!wasm_runtime_init())
{
fprintf(stderr,"wasm runtime initialisation failed\n");
exit(EXIT_FAILURE);
}
/* read WASM file into a memory buffer */
buffer = read_wasm_binary_to_buffer(argv[1], &size);
if(buffer == NULL)
{
fprintf(stderr, "the returned buffer for reading the wasm module is null\n");
exit(EXIT_FAILURE);
}
/* add line below if we want to export native functions to WASM app */
int n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol);
if (!wasm_runtime_register_natives("env", native_symbols, n_native_symbols))
{
free(buffer);
exit(EXIT_FAILURE);
}
/* parse the WASM file from buffer and create a WASM module */
module = wasm_runtime_load(buffer, size, error_buf, sizeof(error_buf));
/* create an instance of the WASM module (WASM linear memory is ready) */
module_inst = wasm_runtime_instantiate(module, stack_size, heap_size,
error_buf, sizeof(error_buf));
if(module_inst == NULL)
{
fprintf(stderr, "module instantiation failed!\n");
exit(EXIT_FAILURE);
}
/* lookup a WASM function by its name
The function signature can NULL here */
func = wasm_runtime_lookup_function(module_inst, "main", NULL);
if (func == NULL) {
printf("main function not found\n");
return -1;
}
/* creat an execution environment to execute the WASM functions */
exec_env = wasm_runtime_create_exec_env(module_inst, stack_size);
if (exec_env == NULL) {
printf("execution environmnet creation failed\n");
return -1;
}
uint32_t args[1] = {0};
if (wasm_runtime_call_wasm(exec_env, func, 0, args) ) {
/* the return value is stored in argv[0] */
printf("main function returned\n");
}
else {
/* exception is thrown if call fails */
printf("%s\n", wasm_runtime_get_exception(module_inst));
}
wasm_runtime_destroy();
return 0;
}