/
test-module-import-instantiate.c
149 lines (117 loc) 路 5.03 KB
/
test-module-import-instantiate.c
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
#include <stdio.h>
#include "../wasmer.h"
#include <assert.h>
#include <stdint.h>
#include <string.h>
typedef struct {
int32_t amount;
int32_t value;
} counter_data;
typedef struct {
uint8_t* bytes;
long bytes_len;
} wasm_file_t;
wasm_file_t read_wasm_file(const char* file_name) {
wasm_file_t wasm_file;
FILE *file = fopen(file_name, "r");
fseek(file, 0, SEEK_END);
wasm_file.bytes_len = ftell(file);
wasm_file.bytes = malloc(wasm_file.bytes_len);
fseek(file, 0, SEEK_SET);
fread(wasm_file.bytes, 1, wasm_file.bytes_len, file);
fclose(file);
return wasm_file;
}
void inc_counter(wasmer_instance_context_t *ctx) {
counter_data* data = (counter_data*)wasmer_instance_context_data_get(ctx);
data->value = data->value + data->amount;
}
void mul_counter(wasmer_instance_context_t *ctx) {
counter_data* data = (counter_data*)wasmer_instance_context_data_get(ctx);
data->value = data->value * data->amount;
}
int32_t get_counter(wasmer_instance_context_t *ctx) {
counter_data* data = (counter_data*)wasmer_instance_context_data_get(ctx);
return data->value;
}
counter_data *init_counter(int32_t value, int32_t amount) {
counter_data* counter = malloc(sizeof(counter_data));
counter->value = value;
counter->amount = amount;
return counter;
}
wasmer_import_t create_import(char* module_name, char* import_name, wasmer_import_func_t *func) {
wasmer_import_t import;
wasmer_byte_array module_name_bytes;
wasmer_byte_array import_name_bytes;
module_name_bytes.bytes = (const uint8_t *) module_name;
module_name_bytes.bytes_len = strlen(module_name);
import_name_bytes.bytes = (const uint8_t *) import_name;
import_name_bytes.bytes_len = strlen(import_name);
import.module_name = module_name_bytes;
import.import_name = import_name_bytes;
import.tag = WASM_FUNCTION;
import.value.func = func;
return import;
}
int main()
{
// Prepare Imports
wasmer_value_tag inc_params_sig[] = {};
wasmer_value_tag inc_returns_sig[] = {};
wasmer_import_func_t *inc_func = wasmer_import_func_new((void (*)(void *)) inc_counter, inc_params_sig, 0, inc_returns_sig, 0);
wasmer_import_t inc_import = create_import("env", "inc", inc_func);
wasmer_value_tag mul_params_sig[] = {};
wasmer_value_tag mul_returns_sig[] = {};
wasmer_import_func_t *mul_func = wasmer_import_func_new((void (*)(void *)) mul_counter, mul_params_sig, 0, mul_returns_sig, 0);
wasmer_import_t mul_import = create_import("env", "mul", mul_func);
wasmer_value_tag get_params_sig[] = {};
wasmer_value_tag get_returns_sig[] = {WASM_I32};
wasmer_import_func_t *get_func = wasmer_import_func_new((void (*)(void *)) get_counter, get_params_sig, 0, get_returns_sig, 1);
wasmer_import_t get_import = create_import("env", "get", get_func);
// Read the wasm file
wasm_file_t wasm_file = read_wasm_file("assets/inc.wasm");
// Compile module
wasmer_module_t *module = NULL;
wasmer_result_t compile_res = wasmer_compile(&module, wasm_file.bytes, wasm_file.bytes_len);
assert(compile_res == WASMER_OK);
// Prepare Import Object
wasmer_import_object_t *import_object = wasmer_import_object_new();
// First, we import `inc_counter` and `mul_counter`
wasmer_import_t imports[] = {inc_import, mul_import};
wasmer_result_t extend_res = wasmer_import_object_extend(import_object, imports, 2);
assert(extend_res == WASMER_OK);
// Now, we'll import `inc_counter` and `mul_counter`
wasmer_import_t more_imports[] = {get_import};
wasmer_result_t extend_res2 = wasmer_import_object_extend(import_object, more_imports, 1);
assert(extend_res2 == WASMER_OK);
// Same `wasmer_import_object_extend` as the first, doesn't affect anything
wasmer_result_t extend_res3 = wasmer_import_object_extend(import_object, imports, 2);
assert(extend_res3 == WASMER_OK);
// Instantiate instance
printf("Instantiating\n");
wasmer_instance_t *instance = NULL;
wasmer_result_t instantiate_res = wasmer_module_import_instantiate(&instance, module, import_object);
printf("Compile result: %d\n", instantiate_res);
assert(instantiate_res == WASMER_OK);
// Init counter
counter_data *counter = init_counter(2, 5);
wasmer_instance_context_data_set(instance, counter);
wasmer_value_t result_one;
wasmer_value_t params[] = {};
wasmer_value_t results[] = {result_one};
wasmer_result_t call1_result = wasmer_instance_call(instance, "inc_and_get", params, 0, results, 1);
printf("Call result: %d\n", call1_result);
printf("Result: %d\n", results[0].value.I32);
wasmer_result_t call2_result = wasmer_instance_call(instance, "mul_and_get", params, 0, results, 1);
printf("Call result: %d\n", call2_result);
printf("Result: %d\n", results[0].value.I32);
// Clear resources
wasmer_import_func_destroy(inc_func);
wasmer_import_func_destroy(mul_func);
wasmer_import_func_destroy(get_func);
wasmer_instance_destroy(instance);
free(counter);
free(wasm_file.bytes);
return 0;
}