Configuration.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/MemoryStream.h>
  7. #include <LibWasm/AbstractMachine/Configuration.h>
  8. #include <LibWasm/AbstractMachine/Interpreter.h>
  9. #include <LibWasm/Printer/Printer.h>
  10. namespace Wasm {
  11. void Configuration::unwind(Badge<CallFrameHandle>, CallFrameHandle const& frame_handle)
  12. {
  13. auto frame = m_frame_stack.take_last();
  14. m_depth--;
  15. m_ip = frame_handle.ip;
  16. }
  17. Result Configuration::call(Interpreter& interpreter, FunctionAddress address, Vector<Value> arguments)
  18. {
  19. auto* function = m_store.get(address);
  20. if (!function)
  21. return Trap {};
  22. if (auto* wasm_function = function->get_pointer<WasmFunction>()) {
  23. Vector<Value> locals = move(arguments);
  24. locals.ensure_capacity(locals.size() + wasm_function->code().func().locals().size());
  25. for (auto& local : wasm_function->code().func().locals()) {
  26. for (size_t i = 0; i < local.n(); ++i)
  27. locals.append(Value(local.type()));
  28. }
  29. set_frame(Frame {
  30. wasm_function->module(),
  31. move(locals),
  32. wasm_function->code().func().body(),
  33. wasm_function->type().results().size(),
  34. });
  35. m_ip = 0;
  36. return execute(interpreter);
  37. }
  38. // It better be a host function, else something is really wrong.
  39. auto& host_function = function->get<HostFunction>();
  40. return host_function.function()(*this, arguments);
  41. }
  42. Result Configuration::execute(Interpreter& interpreter)
  43. {
  44. interpreter.interpret(*this);
  45. if (interpreter.did_trap())
  46. return Trap { interpreter.trap_reason() };
  47. Vector<Value> results;
  48. results.ensure_capacity(frame().arity());
  49. for (size_t i = 0; i < frame().arity(); ++i)
  50. results.unchecked_append(value_stack().take_last());
  51. label_stack().take_last();
  52. return Result { move(results) };
  53. }
  54. void Configuration::dump_stack()
  55. {
  56. auto print_value = []<typename... Ts>(CheckedFormatString<Ts...> format, Ts... vs) {
  57. AllocatingMemoryStream memory_stream;
  58. Printer { memory_stream }.print(vs...);
  59. auto buffer = ByteBuffer::create_uninitialized(memory_stream.used_buffer_size()).release_value_but_fixme_should_propagate_errors();
  60. memory_stream.read_until_filled(buffer).release_value_but_fixme_should_propagate_errors();
  61. dbgln(format.view(), StringView(buffer).trim_whitespace());
  62. };
  63. for (auto const& value : value_stack()) {
  64. print_value(" {}", value);
  65. }
  66. }
  67. }