summaryrefslogtreecommitdiff
path: root/deps/v8/third_party/wasm-api/example/reflect.cc
blob: e0f8ba6856857b1a1c35b9e4458d5f0e1fdedbef (plain)
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
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <cinttypes>

#include "wasm.hh"


auto operator<<(std::ostream& out, wasm::Mutability mut) -> std::ostream& {
  switch (mut) {
    case wasm::VAR: return out << "var";
    case wasm::CONST: return out << "const";
  }
  return out;
}

auto operator<<(std::ostream& out, wasm::Limits limits) -> std::ostream& {
  out << limits.min;
  if (limits.max < wasm::Limits(0).max) out << " " << limits.max;
  return out;
}

auto operator<<(std::ostream& out, const wasm::ValType& type) -> std::ostream& {
  switch (type.kind()) {
    case wasm::I32: return out << "i32";
    case wasm::I64: return out << "i64";
    case wasm::F32: return out << "f32";
    case wasm::F64: return out << "f64";
    case wasm::ANYREF: return out << "anyref";
    case wasm::FUNCREF: return out << "funcref";
  }
  return out;
}

auto operator<<(std::ostream& out, const wasm::ownvec<wasm::ValType>& types) -> std::ostream& {
  bool first = true;
  for (size_t i = 0; i < types.size(); ++i) {
    if (first) {
      first = false;
    } else {
      out << " ";
    }
    out << *types[i].get();
  }
  return out;
}

auto operator<<(std::ostream& out, const wasm::ExternType& type) -> std::ostream& {
  switch (type.kind()) {
    case wasm::EXTERN_FUNC: {
      out << "func " << type.func()->params() << " -> " << type.func()->results();
    } break;
    case wasm::EXTERN_GLOBAL: {
      out << "global " << type.global()->mutability() << " " << *type.global()->content();
    } break;
    case wasm::EXTERN_TABLE: {
      out << "table " << type.table()->limits() << " " << *type.table()->element();
    } break;
    case wasm::EXTERN_MEMORY: {
      out << "memory " << type.memory()->limits();
    } break;
  }
  return out;
}

auto operator<<(std::ostream& out, const wasm::Name& name) -> std::ostream& {
  out << "\"" << std::string(name.get(), name.size()) << "\"";
  return out;
}


void run() {
  // Initialize.
  std::cout << "Initializing..." << std::endl;
  auto engine = wasm::Engine::make();
  auto store_ = wasm::Store::make(engine.get());
  auto store = store_.get();

  // Load binary.
  std::cout << "Loading binary..." << std::endl;
  std::ifstream file("reflect.wasm");
  file.seekg(0, std::ios_base::end);
  auto file_size = file.tellg();
  file.seekg(0);
  auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
  file.read(binary.get(), file_size);
  file.close();
  if (file.fail()) {
    std::cout << "> Error loading module!" << std::endl;
    exit(1);
  }

  // Compile.
  std::cout << "Compiling module..." << std::endl;
  auto module = wasm::Module::make(store, binary);
  if (!module) {
    std::cout << "> Error compiling module!" << std::endl;
    exit(1);
  }

  // Instantiate.
  std::cout << "Instantiating module..." << std::endl;
  auto instance = wasm::Instance::make(store, module.get(), nullptr);
  if (!instance) {
    std::cout << "> Error instantiating module!" << std::endl;
    exit(1);
  }

  // Extract exports.
  std::cout << "Extracting export..." << std::endl;
  auto export_types = module->exports();
  auto exports = instance->exports();
  assert(exports.size() == export_types.size());

  for (size_t i = 0; i < exports.size(); ++i) {
    assert(exports[i]->kind() == export_types[i]->type()->kind());
    std::cout << "> export " << i << " " << export_types[i]->name() << std::endl;
    std::cout << ">> initial: " << *export_types[i]->type() << std::endl;
    std::cout << ">> current: " << *exports[i]->type() << std::endl;
    if (exports[i]->kind() == wasm::EXTERN_FUNC) {
      auto func = exports[i]->func();
      std::cout << ">> in-arity: " << func->param_arity();
      std::cout << ", out-arity: " << func->result_arity() << std::endl;
    }
  }

  // Shut down.
  std::cout << "Shutting down..." << std::endl;
}


int main(int argc, const char* argv[]) {
  run();
  std::cout << "Done." << std::endl;
  return 0;
}