AbstractMachine.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  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 <AK/Function.h>
  8. #include <AK/HashMap.h>
  9. #include <AK/HashTable.h>
  10. #include <AK/OwnPtr.h>
  11. #include <AK/Result.h>
  12. #include <LibWasm/Types.h>
  13. namespace Wasm {
  14. class Configuration;
  15. struct Interpreter;
  16. struct InstantiationError {
  17. String error { "Unknown error" };
  18. };
  19. struct LinkError {
  20. enum OtherErrors {
  21. InvalidImportedModule,
  22. };
  23. Vector<String> missing_imports;
  24. Vector<OtherErrors> other_errors;
  25. };
  26. TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, true, true, false, false, false, true, FunctionAddress);
  27. TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, true, true, false, false, false, true, ExternAddress);
  28. TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, true, true, false, false, false, true, TableAddress);
  29. TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, true, true, false, false, false, true, GlobalAddress);
  30. TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, true, true, false, false, false, true, MemoryAddress);
  31. // FIXME: These should probably be made generic/virtual if/when we decide to do something more
  32. // fancy than just a dumb interpreter.
  33. class Value {
  34. public:
  35. using AnyValueType = Variant<i32, i64, float, double, FunctionAddress, ExternAddress>;
  36. explicit Value(AnyValueType value)
  37. : m_value(move(value))
  38. , m_type(ValueType::I32)
  39. {
  40. if (m_value.has<i32>())
  41. m_type = ValueType { ValueType::I32 };
  42. else if (m_value.has<i64>())
  43. m_type = ValueType { ValueType::I64 };
  44. else if (m_value.has<float>())
  45. m_type = ValueType { ValueType::F32 };
  46. else if (m_value.has<double>())
  47. m_type = ValueType { ValueType::F64 };
  48. else if (m_value.has<FunctionAddress>())
  49. m_type = ValueType { ValueType::FunctionReference };
  50. else if (m_value.has<ExternAddress>())
  51. m_type = ValueType { ValueType::ExternReference };
  52. else
  53. VERIFY_NOT_REACHED();
  54. }
  55. template<typename T>
  56. requires(sizeof(T) == sizeof(u64)) explicit Value(ValueType type, T raw_value)
  57. : m_value(0)
  58. , m_type(type)
  59. {
  60. switch (type.kind()) {
  61. case ValueType::Kind::ExternReference:
  62. m_value = ExternAddress { bit_cast<u64>(raw_value) };
  63. break;
  64. case ValueType::Kind::FunctionReference:
  65. m_value = FunctionAddress { bit_cast<u64>(raw_value) };
  66. break;
  67. case ValueType::Kind::I32:
  68. m_value = static_cast<i32>(bit_cast<i64>(raw_value));
  69. break;
  70. case ValueType::Kind::I64:
  71. m_value = static_cast<i64>(bit_cast<u64>(raw_value));
  72. break;
  73. case ValueType::Kind::F32:
  74. m_value = static_cast<float>(bit_cast<double>(raw_value));
  75. break;
  76. case ValueType::Kind::F64:
  77. m_value = bit_cast<double>(raw_value);
  78. break;
  79. default:
  80. VERIFY_NOT_REACHED();
  81. }
  82. }
  83. Value(const Value& value)
  84. : m_value(AnyValueType { value.m_value })
  85. , m_type(value.m_type)
  86. {
  87. }
  88. Value(Value&& value)
  89. : m_value(move(value.m_value))
  90. , m_type(move(value.m_type))
  91. {
  92. }
  93. Value& operator=(Value&& value)
  94. {
  95. m_value = move(value.m_value);
  96. m_type = move(value.m_type);
  97. return *this;
  98. }
  99. template<typename T>
  100. Optional<T> to()
  101. {
  102. Optional<T> result;
  103. m_value.visit(
  104. [&](auto value) {
  105. if constexpr (IsSame<T, decltype(value)>)
  106. result = value;
  107. else if constexpr (!IsFloatingPoint<T> && IsSame<decltype(value), MakeSigned<T>>)
  108. result = value;
  109. },
  110. [&](const FunctionAddress& address) {
  111. if constexpr (IsSame<T, FunctionAddress>)
  112. result = address;
  113. },
  114. [&](const ExternAddress& address) {
  115. if constexpr (IsSame<T, ExternAddress>)
  116. result = address;
  117. });
  118. return result;
  119. }
  120. auto& type() const { return m_type; }
  121. auto& value() const { return m_value; }
  122. private:
  123. AnyValueType m_value;
  124. ValueType m_type;
  125. };
  126. struct Trap {
  127. // Empty value type
  128. };
  129. class Result {
  130. public:
  131. explicit Result(Vector<Value> values)
  132. : m_values(move(values))
  133. {
  134. }
  135. Result(Trap)
  136. : m_is_trap(true)
  137. {
  138. }
  139. auto& values() const { return m_values; }
  140. auto& values() { return m_values; }
  141. auto is_trap() const { return m_is_trap; }
  142. private:
  143. Vector<Value> m_values;
  144. bool m_is_trap { false };
  145. };
  146. using ExternValue = Variant<FunctionAddress, TableAddress, MemoryAddress, GlobalAddress>;
  147. class ExportInstance {
  148. public:
  149. explicit ExportInstance(String name, ExternValue value)
  150. : m_name(move(name))
  151. , m_value(move(value))
  152. {
  153. }
  154. auto& name() const { return m_name; }
  155. auto& value() const { return m_value; }
  156. private:
  157. String m_name;
  158. ExternValue m_value;
  159. };
  160. class ModuleInstance {
  161. public:
  162. explicit ModuleInstance(
  163. Vector<FunctionType> types, Vector<FunctionAddress> function_addresses, Vector<TableAddress> table_addresses,
  164. Vector<MemoryAddress> memory_addresses, Vector<GlobalAddress> global_addresses, Vector<ExportInstance> exports)
  165. : m_types(move(types))
  166. , m_functions(move(function_addresses))
  167. , m_tables(move(table_addresses))
  168. , m_memories(move(memory_addresses))
  169. , m_globals(move(global_addresses))
  170. , m_exports(move(exports))
  171. {
  172. }
  173. ModuleInstance() = default;
  174. auto& types() const { return m_types; }
  175. auto& functions() const { return m_functions; }
  176. auto& tables() const { return m_tables; }
  177. auto& memories() const { return m_memories; }
  178. auto& globals() const { return m_globals; }
  179. auto& exports() const { return m_exports; }
  180. auto& types() { return m_types; }
  181. auto& functions() { return m_functions; }
  182. auto& tables() { return m_tables; }
  183. auto& memories() { return m_memories; }
  184. auto& globals() { return m_globals; }
  185. auto& exports() { return m_exports; }
  186. private:
  187. Vector<FunctionType> m_types;
  188. Vector<FunctionAddress> m_functions;
  189. Vector<TableAddress> m_tables;
  190. Vector<MemoryAddress> m_memories;
  191. Vector<GlobalAddress> m_globals;
  192. Vector<ExportInstance> m_exports;
  193. };
  194. class WasmFunction {
  195. public:
  196. explicit WasmFunction(const FunctionType& type, const ModuleInstance& module, const Module::Function& code)
  197. : m_type(type)
  198. , m_module(module)
  199. , m_code(code)
  200. {
  201. }
  202. auto& type() const { return m_type; }
  203. auto& module() const { return m_module; }
  204. auto& code() const { return m_code; }
  205. private:
  206. FunctionType m_type;
  207. const ModuleInstance& m_module;
  208. const Module::Function& m_code;
  209. };
  210. class HostFunction {
  211. public:
  212. explicit HostFunction(AK::Function<Result(Configuration&, Vector<Value>&)> function, const FunctionType& type)
  213. : m_function(move(function))
  214. , m_type(type)
  215. {
  216. }
  217. auto& function() { return m_function; }
  218. auto& type() const { return m_type; }
  219. private:
  220. AK::Function<Result(Configuration&, Vector<Value>&)> m_function;
  221. FunctionType m_type;
  222. };
  223. using FunctionInstance = Variant<WasmFunction, HostFunction>;
  224. class Reference {
  225. public:
  226. struct Null {
  227. ValueType type;
  228. };
  229. struct Func {
  230. FunctionAddress address;
  231. };
  232. struct Extern {
  233. ExternAddress address;
  234. };
  235. using RefType = Variant<Null, Func, Extern>;
  236. explicit Reference(RefType ref)
  237. : m_ref(move(ref))
  238. {
  239. }
  240. auto& ref() const { return m_ref; }
  241. private:
  242. RefType m_ref;
  243. };
  244. class TableInstance {
  245. public:
  246. explicit TableInstance(const TableType& type, Vector<Optional<Reference>> elements)
  247. : m_elements(move(elements))
  248. , m_type(type)
  249. {
  250. }
  251. auto& elements() const { return m_elements; }
  252. auto& elements() { return m_elements; }
  253. auto& type() const { return m_type; }
  254. private:
  255. Vector<Optional<Reference>> m_elements;
  256. const TableType& m_type;
  257. };
  258. class MemoryInstance {
  259. public:
  260. explicit MemoryInstance(const MemoryType& type)
  261. : m_type(type)
  262. {
  263. grow(m_type.limits().min() * Constants::page_size);
  264. }
  265. auto& type() const { return m_type; }
  266. auto size() const { return m_size; }
  267. auto& data() const { return m_data; }
  268. auto& data() { return m_data; }
  269. bool grow(size_t size_to_grow)
  270. {
  271. if (size_to_grow == 0)
  272. return true;
  273. auto new_size = m_data.size() + size_to_grow;
  274. if (m_type.limits().max().value_or(new_size) < new_size)
  275. return false;
  276. auto previous_size = m_size;
  277. m_data.grow(new_size);
  278. m_size = new_size;
  279. // The spec requires that we zero out everything on grow
  280. __builtin_memset(m_data.offset_pointer(previous_size), 0, size_to_grow);
  281. return true;
  282. }
  283. private:
  284. const MemoryType& m_type;
  285. size_t m_size { 0 };
  286. ByteBuffer m_data;
  287. };
  288. class GlobalInstance {
  289. public:
  290. explicit GlobalInstance(Value value, bool is_mutable)
  291. : m_mutable(is_mutable)
  292. , m_value(move(value))
  293. {
  294. }
  295. auto is_mutable() const { return m_mutable; }
  296. auto& value() const { return m_value; }
  297. void set_value(Value value)
  298. {
  299. VERIFY(is_mutable());
  300. m_value = move(value);
  301. }
  302. private:
  303. bool m_mutable { false };
  304. Value m_value;
  305. };
  306. class Store {
  307. public:
  308. Store() = default;
  309. Optional<FunctionAddress> allocate(ModuleInstance& module, const Module::Function& function);
  310. Optional<FunctionAddress> allocate(HostFunction&&);
  311. Optional<TableAddress> allocate(const TableType&);
  312. Optional<MemoryAddress> allocate(const MemoryType&);
  313. Optional<GlobalAddress> allocate(const GlobalType&, Value);
  314. FunctionInstance* get(FunctionAddress);
  315. TableInstance* get(TableAddress);
  316. MemoryInstance* get(MemoryAddress);
  317. GlobalInstance* get(GlobalAddress);
  318. private:
  319. Vector<FunctionInstance> m_functions;
  320. Vector<TableInstance> m_tables;
  321. Vector<MemoryInstance> m_memories;
  322. Vector<GlobalInstance> m_globals;
  323. };
  324. class Label {
  325. public:
  326. explicit Label(size_t arity, InstructionPointer continuation)
  327. : m_arity(arity)
  328. , m_continuation(continuation)
  329. {
  330. }
  331. auto continuation() const { return m_continuation; }
  332. auto arity() const { return m_arity; }
  333. private:
  334. size_t m_arity { 0 };
  335. InstructionPointer m_continuation;
  336. };
  337. class Frame {
  338. AK_MAKE_NONCOPYABLE(Frame);
  339. public:
  340. explicit Frame(const ModuleInstance& module, Vector<Value> locals, const Expression& expression, size_t arity)
  341. : m_module(module)
  342. , m_locals(move(locals))
  343. , m_expression(expression)
  344. , m_arity(arity)
  345. {
  346. }
  347. auto& module() const { return m_module; }
  348. auto& locals() const { return m_locals; }
  349. auto& locals() { return m_locals; }
  350. auto& expression() const { return m_expression; }
  351. auto arity() const { return m_arity; }
  352. private:
  353. const ModuleInstance& m_module;
  354. Vector<Value> m_locals;
  355. const Expression& m_expression;
  356. size_t m_arity { 0 };
  357. };
  358. class Stack {
  359. public:
  360. using EntryType = Variant<NonnullOwnPtr<Value>, NonnullOwnPtr<Label>, NonnullOwnPtr<Frame>>;
  361. Stack() = default;
  362. [[nodiscard]] bool is_empty() const { return m_data.is_empty(); }
  363. void push(EntryType entry) { m_data.append(move(entry)); }
  364. auto pop() { return m_data.take_last(); }
  365. auto& peek() const { return m_data.last(); }
  366. auto size() const { return m_data.size(); }
  367. auto& entries() const { return m_data; }
  368. private:
  369. Vector<EntryType> m_data;
  370. };
  371. using InstantiationResult = AK::Result<NonnullOwnPtr<ModuleInstance>, InstantiationError>;
  372. class AbstractMachine {
  373. public:
  374. explicit AbstractMachine() = default;
  375. // Load and instantiate a module, and link it into this interpreter.
  376. InstantiationResult instantiate(const Module&, Vector<ExternValue>);
  377. Result invoke(FunctionAddress, Vector<Value>);
  378. auto& store() const { return m_store; }
  379. auto& store() { return m_store; }
  380. Function<bool(Configuration&, InstructionPointer&, const Instruction&)> pre_interpret_hook;
  381. Function<bool(Configuration&, InstructionPointer&, const Instruction&, const Interpreter&)> post_interpret_hook;
  382. private:
  383. Optional<InstantiationError> allocate_all(const Module&, ModuleInstance&, Vector<ExternValue>&, Vector<Value>& global_values);
  384. Store m_store;
  385. };
  386. class Linker {
  387. public:
  388. struct Name {
  389. String module;
  390. String name;
  391. ImportSection::Import::ImportDesc type;
  392. };
  393. explicit Linker(const Module& module)
  394. : m_module(module)
  395. {
  396. }
  397. // Link a module, the import 'module name' is ignored with this.
  398. void link(const ModuleInstance&);
  399. // Link a bunch of qualified values, also matches 'module name'.
  400. void link(const HashMap<Name, ExternValue>&);
  401. auto& unresolved_imports()
  402. {
  403. populate();
  404. return m_unresolved_imports;
  405. }
  406. AK::Result<Vector<ExternValue>, LinkError> finish();
  407. private:
  408. void populate();
  409. const Module& m_module;
  410. HashMap<Name, ExternValue> m_resolved_imports;
  411. HashTable<Name> m_unresolved_imports;
  412. Vector<Name> m_ordered_imports;
  413. Optional<LinkError> m_error;
  414. };
  415. }
  416. template<>
  417. struct AK::Traits<Wasm::Linker::Name> : public AK::GenericTraits<Wasm::Linker::Name> {
  418. static constexpr bool is_trivial() { return false; }
  419. static unsigned hash(const Wasm::Linker::Name& entry) { return pair_int_hash(entry.module.hash(), entry.name.hash()); }
  420. static bool equals(const Wasm::Linker::Name& a, const Wasm::Linker::Name& b) { return a.name == b.name && a.module == b.module; }
  421. };