1 #include <iostream>
2 #include <fstream>
3 #include <cstdlib>
4 #include <string>
5 #include <cinttypes>
6
7 #include "wasm.hh"
8
9
operator <<(std::ostream & out,wasm::Mutability mut)10 auto operator<<(std::ostream& out, wasm::Mutability mut) -> std::ostream& {
11 switch (mut) {
12 case wasm::VAR: return out << "var";
13 case wasm::CONST: return out << "const";
14 }
15 return out;
16 }
17
operator <<(std::ostream & out,wasm::Limits limits)18 auto operator<<(std::ostream& out, wasm::Limits limits) -> std::ostream& {
19 out << limits.min;
20 if (limits.max < wasm::Limits(0).max) out << " " << limits.max;
21 return out;
22 }
23
operator <<(std::ostream & out,const wasm::ValType & type)24 auto operator<<(std::ostream& out, const wasm::ValType& type) -> std::ostream& {
25 switch (type.kind()) {
26 case wasm::I32: return out << "i32";
27 case wasm::I64: return out << "i64";
28 case wasm::F32: return out << "f32";
29 case wasm::F64: return out << "f64";
30 case wasm::ANYREF: return out << "anyref";
31 case wasm::FUNCREF: return out << "funcref";
32 }
33 return out;
34 }
35
operator <<(std::ostream & out,const wasm::ownvec<wasm::ValType> & types)36 auto operator<<(std::ostream& out, const wasm::ownvec<wasm::ValType>& types) -> std::ostream& {
37 bool first = true;
38 for (size_t i = 0; i < types.size(); ++i) {
39 if (first) {
40 first = false;
41 } else {
42 out << " ";
43 }
44 out << *types[i].get();
45 }
46 return out;
47 }
48
operator <<(std::ostream & out,const wasm::ExternType & type)49 auto operator<<(std::ostream& out, const wasm::ExternType& type) -> std::ostream& {
50 switch (type.kind()) {
51 case wasm::EXTERN_FUNC: {
52 out << "func " << type.func()->params() << " -> " << type.func()->results();
53 } break;
54 case wasm::EXTERN_GLOBAL: {
55 out << "global " << type.global()->mutability() << " " << *type.global()->content();
56 } break;
57 case wasm::EXTERN_TABLE: {
58 out << "table " << type.table()->limits() << " " << *type.table()->element();
59 } break;
60 case wasm::EXTERN_MEMORY: {
61 out << "memory " << type.memory()->limits();
62 } break;
63 }
64 return out;
65 }
66
operator <<(std::ostream & out,const wasm::Name & name)67 auto operator<<(std::ostream& out, const wasm::Name& name) -> std::ostream& {
68 out << "\"" << std::string(name.get(), name.size()) << "\"";
69 return out;
70 }
71
72
run()73 void run() {
74 // Initialize.
75 std::cout << "Initializing..." << std::endl;
76 auto engine = wasm::Engine::make();
77 auto store_ = wasm::Store::make(engine.get());
78 auto store = store_.get();
79
80 // Load binary.
81 std::cout << "Loading binary..." << std::endl;
82 std::ifstream file("reflect.wasm");
83 file.seekg(0, std::ios_base::end);
84 auto file_size = file.tellg();
85 file.seekg(0);
86 auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
87 file.read(binary.get(), file_size);
88 file.close();
89 if (file.fail()) {
90 std::cout << "> Error loading module!" << std::endl;
91 exit(1);
92 }
93
94 // Compile.
95 std::cout << "Compiling module..." << std::endl;
96 auto module = wasm::Module::make(store, binary);
97 if (!module) {
98 std::cout << "> Error compiling module!" << std::endl;
99 exit(1);
100 }
101
102 // Instantiate.
103 std::cout << "Instantiating module..." << std::endl;
104 auto instance = wasm::Instance::make(store, module.get(), nullptr);
105 if (!instance) {
106 std::cout << "> Error instantiating module!" << std::endl;
107 exit(1);
108 }
109
110 // Extract exports.
111 std::cout << "Extracting export..." << std::endl;
112 auto export_types = module->exports();
113 auto exports = instance->exports();
114 assert(exports.size() == export_types.size());
115
116 for (size_t i = 0; i < exports.size(); ++i) {
117 assert(exports[i]->kind() == export_types[i]->type()->kind());
118 std::cout << "> export " << i << " " << export_types[i]->name() << std::endl;
119 std::cout << ">> initial: " << *export_types[i]->type() << std::endl;
120 std::cout << ">> current: " << *exports[i]->type() << std::endl;
121 if (exports[i]->kind() == wasm::EXTERN_FUNC) {
122 auto func = exports[i]->func();
123 std::cout << ">> in-arity: " << func->param_arity();
124 std::cout << ", out-arity: " << func->result_arity() << std::endl;
125 }
126 }
127
128 // Shut down.
129 std::cout << "Shutting down..." << std::endl;
130 }
131
132
main(int argc,const char * argv[])133 int main(int argc, const char* argv[]) {
134 run();
135 std::cout << "Done." << std::endl;
136 return 0;
137 }
138
139