AbstractMachine.h 13 KB

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