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// A function to be called from Wasm code.
101cb0ef41Sopenharmony_ciauto callback(
111cb0ef41Sopenharmony_ci  const wasm::Val args[], wasm::Val results[]
121cb0ef41Sopenharmony_ci) -> wasm::own<wasm::Trap> {
131cb0ef41Sopenharmony_ci  std::cout << "Calling back..." << std::endl;
141cb0ef41Sopenharmony_ci  std::cout << "> " << args[0].i32();
151cb0ef41Sopenharmony_ci  std::cout << " " << args[1].i64();
161cb0ef41Sopenharmony_ci  std::cout << " " << args[2].i64();
171cb0ef41Sopenharmony_ci  std::cout << " " << args[3].i32() << std::endl;
181cb0ef41Sopenharmony_ci  results[0] = args[3].copy();
191cb0ef41Sopenharmony_ci  results[1] = args[1].copy();
201cb0ef41Sopenharmony_ci  results[2] = args[2].copy();
211cb0ef41Sopenharmony_ci  results[3] = args[0].copy();
221cb0ef41Sopenharmony_ci  return nullptr;
231cb0ef41Sopenharmony_ci}
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_civoid run() {
271cb0ef41Sopenharmony_ci  // Initialize.
281cb0ef41Sopenharmony_ci  std::cout << "Initializing..." << std::endl;
291cb0ef41Sopenharmony_ci  auto engine = wasm::Engine::make();
301cb0ef41Sopenharmony_ci  auto store_ = wasm::Store::make(engine.get());
311cb0ef41Sopenharmony_ci  auto store = store_.get();
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci  // Load binary.
341cb0ef41Sopenharmony_ci  std::cout << "Loading binary..." << std::endl;
351cb0ef41Sopenharmony_ci  std::ifstream file("multi.wasm");
361cb0ef41Sopenharmony_ci  file.seekg(0, std::ios_base::end);
371cb0ef41Sopenharmony_ci  auto file_size = file.tellg();
381cb0ef41Sopenharmony_ci  file.seekg(0);
391cb0ef41Sopenharmony_ci  auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
401cb0ef41Sopenharmony_ci  file.read(binary.get(), file_size);
411cb0ef41Sopenharmony_ci  file.close();
421cb0ef41Sopenharmony_ci  if (file.fail()) {
431cb0ef41Sopenharmony_ci    std::cout << "> Error loading module!" << std::endl;
441cb0ef41Sopenharmony_ci    exit(1);
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  // Compile.
481cb0ef41Sopenharmony_ci  std::cout << "Compiling module..." << std::endl;
491cb0ef41Sopenharmony_ci  auto module = wasm::Module::make(store, binary);
501cb0ef41Sopenharmony_ci  if (!module) {
511cb0ef41Sopenharmony_ci    std::cout << "> Error compiling module!" << std::endl;
521cb0ef41Sopenharmony_ci    exit(1);
531cb0ef41Sopenharmony_ci  }
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  // Create external print functions.
561cb0ef41Sopenharmony_ci  std::cout << "Creating callback..." << std::endl;
571cb0ef41Sopenharmony_ci  auto tuple = wasm::ownvec<wasm::ValType>::make(
581cb0ef41Sopenharmony_ci    wasm::ValType::make(wasm::I32),
591cb0ef41Sopenharmony_ci    wasm::ValType::make(wasm::I64),
601cb0ef41Sopenharmony_ci    wasm::ValType::make(wasm::I64),
611cb0ef41Sopenharmony_ci    wasm::ValType::make(wasm::I32)
621cb0ef41Sopenharmony_ci  );
631cb0ef41Sopenharmony_ci  auto callback_type =
641cb0ef41Sopenharmony_ci    wasm::FuncType::make(tuple.deep_copy(), tuple.deep_copy());
651cb0ef41Sopenharmony_ci  auto callback_func = wasm::Func::make(store, callback_type.get(), callback);
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  // Instantiate.
681cb0ef41Sopenharmony_ci  std::cout << "Instantiating module..." << std::endl;
691cb0ef41Sopenharmony_ci  wasm::Extern* imports[] = {callback_func.get()};
701cb0ef41Sopenharmony_ci  auto instance = wasm::Instance::make(store, module.get(), imports);
711cb0ef41Sopenharmony_ci  if (!instance) {
721cb0ef41Sopenharmony_ci    std::cout << "> Error instantiating module!" << std::endl;
731cb0ef41Sopenharmony_ci    exit(1);
741cb0ef41Sopenharmony_ci  }
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci  // Extract export.
771cb0ef41Sopenharmony_ci  std::cout << "Extracting export..." << std::endl;
781cb0ef41Sopenharmony_ci  auto exports = instance->exports();
791cb0ef41Sopenharmony_ci  if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) {
801cb0ef41Sopenharmony_ci    std::cout << "> Error accessing export!" << std::endl;
811cb0ef41Sopenharmony_ci    exit(1);
821cb0ef41Sopenharmony_ci  }
831cb0ef41Sopenharmony_ci  auto run_func = exports[0]->func();
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  // Call.
861cb0ef41Sopenharmony_ci  std::cout << "Calling export..." << std::endl;
871cb0ef41Sopenharmony_ci  wasm::Val args[] = {
881cb0ef41Sopenharmony_ci    wasm::Val::i32(1), wasm::Val::i64(2), wasm::Val::i64(3), wasm::Val::i32(4)
891cb0ef41Sopenharmony_ci  };
901cb0ef41Sopenharmony_ci  wasm::Val results[4];
911cb0ef41Sopenharmony_ci  if (wasm::own<wasm::Trap> trap = run_func->call(args, results)) {
921cb0ef41Sopenharmony_ci    std::cout << "> Error calling function! " << trap->message().get() << std::endl;
931cb0ef41Sopenharmony_ci    exit(1);
941cb0ef41Sopenharmony_ci  }
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  // Print result.
971cb0ef41Sopenharmony_ci  std::cout << "Printing result..." << std::endl;
981cb0ef41Sopenharmony_ci  std::cout << "> " << results[0].i32();
991cb0ef41Sopenharmony_ci  std::cout << " " << results[1].i64();
1001cb0ef41Sopenharmony_ci  std::cout << " " << results[2].i64();
1011cb0ef41Sopenharmony_ci  std::cout << " " << results[3].i32() << std::endl;
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci  assert(results[0].i32() == 4);
1041cb0ef41Sopenharmony_ci  assert(results[1].i64() == 3);
1051cb0ef41Sopenharmony_ci  assert(results[2].i64() == 2);
1061cb0ef41Sopenharmony_ci  assert(results[3].i32() == 1);
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci  // Shut down.
1091cb0ef41Sopenharmony_ci  std::cout << "Shutting down..." << std::endl;
1101cb0ef41Sopenharmony_ci}
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ciint main(int argc, const char* argv[]) {
1141cb0ef41Sopenharmony_ci  run();
1151cb0ef41Sopenharmony_ci  std::cout << "Done." << std::endl;
1161cb0ef41Sopenharmony_ci  return 0;
1171cb0ef41Sopenharmony_ci}
1181cb0ef41Sopenharmony_ci
119