11cb0ef41Sopenharmony_ci#include <iostream>
21cb0ef41Sopenharmony_ci#include <fstream>
31cb0ef41Sopenharmony_ci#include <cstdlib>
41cb0ef41Sopenharmony_ci#include <string>
51cb0ef41Sopenharmony_ci#include <cinttypes>
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "wasm.hh"
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci// A function to be called from Wasm code.
111cb0ef41Sopenharmony_ciauto hello_callback(
121cb0ef41Sopenharmony_ci  const wasm::Val args[], wasm::Val results[]
131cb0ef41Sopenharmony_ci) -> wasm::own<wasm::Trap> {
141cb0ef41Sopenharmony_ci  std::cout << "Calling back..." << std::endl;
151cb0ef41Sopenharmony_ci  std::cout << "> Hello world!" << std::endl;
161cb0ef41Sopenharmony_ci  return nullptr;
171cb0ef41Sopenharmony_ci}
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_civoid run() {
211cb0ef41Sopenharmony_ci  // Initialize.
221cb0ef41Sopenharmony_ci  std::cout << "Initializing..." << std::endl;
231cb0ef41Sopenharmony_ci  auto engine = wasm::Engine::make();
241cb0ef41Sopenharmony_ci  auto store_ = wasm::Store::make(engine.get());
251cb0ef41Sopenharmony_ci  auto store = store_.get();
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci  // Load binary.
281cb0ef41Sopenharmony_ci  std::cout << "Loading binary..." << std::endl;
291cb0ef41Sopenharmony_ci  std::ifstream file("hello.wasm");
301cb0ef41Sopenharmony_ci  file.seekg(0, std::ios_base::end);
311cb0ef41Sopenharmony_ci  auto file_size = file.tellg();
321cb0ef41Sopenharmony_ci  file.seekg(0);
331cb0ef41Sopenharmony_ci  auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
341cb0ef41Sopenharmony_ci  file.read(binary.get(), file_size);
351cb0ef41Sopenharmony_ci  file.close();
361cb0ef41Sopenharmony_ci  if (file.fail()) {
371cb0ef41Sopenharmony_ci    std::cout << "> Error loading module!" << std::endl;
381cb0ef41Sopenharmony_ci    exit(1);
391cb0ef41Sopenharmony_ci  }
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci  // Compile.
421cb0ef41Sopenharmony_ci  std::cout << "Compiling module..." << std::endl;
431cb0ef41Sopenharmony_ci  auto module = wasm::Module::make(store, binary);
441cb0ef41Sopenharmony_ci  if (!module) {
451cb0ef41Sopenharmony_ci    std::cout << "> Error compiling module!" << std::endl;
461cb0ef41Sopenharmony_ci    exit(1);
471cb0ef41Sopenharmony_ci  }
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  // Create external print functions.
501cb0ef41Sopenharmony_ci  std::cout << "Creating callback..." << std::endl;
511cb0ef41Sopenharmony_ci  auto hello_type = wasm::FuncType::make(
521cb0ef41Sopenharmony_ci    wasm::ownvec<wasm::ValType>::make(), wasm::ownvec<wasm::ValType>::make()
531cb0ef41Sopenharmony_ci  );
541cb0ef41Sopenharmony_ci  auto hello_func = wasm::Func::make(store, hello_type.get(), hello_callback);
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  // Instantiate.
571cb0ef41Sopenharmony_ci  std::cout << "Instantiating module..." << std::endl;
581cb0ef41Sopenharmony_ci  wasm::Extern* imports[] = {hello_func.get()};
591cb0ef41Sopenharmony_ci  auto instance = wasm::Instance::make(store, module.get(), imports);
601cb0ef41Sopenharmony_ci  if (!instance) {
611cb0ef41Sopenharmony_ci    std::cout << "> Error instantiating module!" << std::endl;
621cb0ef41Sopenharmony_ci    exit(1);
631cb0ef41Sopenharmony_ci  }
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  // Extract export.
661cb0ef41Sopenharmony_ci  std::cout << "Extracting export..." << std::endl;
671cb0ef41Sopenharmony_ci  auto exports = instance->exports();
681cb0ef41Sopenharmony_ci  if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) {
691cb0ef41Sopenharmony_ci    std::cout << "> Error accessing export!" << std::endl;
701cb0ef41Sopenharmony_ci    exit(1);
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci  auto run_func = exports[0]->func();
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  // Call.
751cb0ef41Sopenharmony_ci  std::cout << "Calling export..." << std::endl;
761cb0ef41Sopenharmony_ci  if (run_func->call()) {
771cb0ef41Sopenharmony_ci    std::cout << "> Error calling function!" << std::endl;
781cb0ef41Sopenharmony_ci    exit(1);
791cb0ef41Sopenharmony_ci  }
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  // Shut down.
821cb0ef41Sopenharmony_ci  std::cout << "Shutting down..." << std::endl;
831cb0ef41Sopenharmony_ci}
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ciint main(int argc, const char* argv[]) {
871cb0ef41Sopenharmony_ci  run();
881cb0ef41Sopenharmony_ci  std::cout << "Done." << std::endl;
891cb0ef41Sopenharmony_ci  return 0;
901cb0ef41Sopenharmony_ci}
911cb0ef41Sopenharmony_ci
92