Configuration.h 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <LibWasm/AbstractMachine/AbstractMachine.h>
  8. namespace Wasm {
  9. class Configuration {
  10. public:
  11. explicit Configuration(Store& store)
  12. : m_store(store)
  13. {
  14. }
  15. Optional<Label> nth_label(size_t label)
  16. {
  17. auto index = nth_label_index(label);
  18. if (index.has_value())
  19. return m_stack.entries()[index.value()].get<Label>();
  20. return {};
  21. }
  22. Optional<size_t> nth_label_index(size_t);
  23. void set_frame(Frame&& frame)
  24. {
  25. m_current_frame_index = m_stack.size();
  26. Label label(frame.arity(), frame.expression().instructions().size());
  27. m_stack.push(move(frame));
  28. m_stack.push(label);
  29. }
  30. ALWAYS_INLINE auto& frame() const { return m_stack.entries()[m_current_frame_index].get<Frame>(); }
  31. ALWAYS_INLINE auto& frame() { return m_stack.entries()[m_current_frame_index].get<Frame>(); }
  32. ALWAYS_INLINE auto& ip() const { return m_ip; }
  33. ALWAYS_INLINE auto& ip() { return m_ip; }
  34. ALWAYS_INLINE auto& depth() const { return m_depth; }
  35. ALWAYS_INLINE auto& depth() { return m_depth; }
  36. ALWAYS_INLINE auto& stack() const { return m_stack; }
  37. ALWAYS_INLINE auto& stack() { return m_stack; }
  38. ALWAYS_INLINE auto& store() const { return m_store; }
  39. ALWAYS_INLINE auto& store() { return m_store; }
  40. struct CallFrameHandle {
  41. explicit CallFrameHandle(Configuration& configuration)
  42. : frame_index(configuration.m_current_frame_index)
  43. , stack_size(configuration.m_stack.size())
  44. , ip(configuration.ip())
  45. , configuration(configuration)
  46. {
  47. configuration.depth()++;
  48. }
  49. ~CallFrameHandle()
  50. {
  51. configuration.unwind({}, *this);
  52. }
  53. size_t frame_index { 0 };
  54. size_t stack_size { 0 };
  55. InstructionPointer ip { 0 };
  56. Configuration& configuration;
  57. };
  58. void unwind(Badge<CallFrameHandle>, CallFrameHandle const&);
  59. Result call(Interpreter&, FunctionAddress, Vector<Value> arguments);
  60. Result execute(Interpreter&);
  61. void enable_instruction_count_limit() { m_should_limit_instruction_count = true; }
  62. bool should_limit_instruction_count() const { return m_should_limit_instruction_count; }
  63. void dump_stack();
  64. private:
  65. Store& m_store;
  66. size_t m_current_frame_index { 0 };
  67. Stack m_stack;
  68. size_t m_depth { 0 };
  69. InstructionPointer m_ip;
  70. bool m_should_limit_instruction_count { false };
  71. };
  72. }