AbstractMachine.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  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. else if constexpr (!IsFloatingPoint<T> && IsSame<decltype(value), MakeSigned<T>>)
  107. result = value;
  108. },
  109. [&](const FunctionAddress& address) {
  110. if constexpr (IsSame<T, FunctionAddress>)
  111. result = address;
  112. },
  113. [&](const ExternAddress& address) {
  114. if constexpr (IsSame<T, ExternAddress>)
  115. result = address;
  116. });
  117. return result;
  118. }
  119. auto& type() const { return m_type; }
  120. auto& value() const { return m_value; }
  121. private:
  122. AnyValueType m_value;
  123. ValueType m_type;
  124. };
  125. struct Trap {
  126. // Empty value type
  127. };
  128. class Result {
  129. public:
  130. explicit Result(Vector<Value> values)
  131. : m_values(move(values))
  132. {
  133. }
  134. Result(Trap)
  135. : m_is_trap(true)
  136. {
  137. }
  138. auto& values() const { return m_values; }
  139. auto& values() { return m_values; }
  140. auto is_trap() const { return m_is_trap; }
  141. private:
  142. Vector<Value> m_values;
  143. bool m_is_trap { false };
  144. };
  145. using ExternValue = Variant<FunctionAddress, TableAddress, MemoryAddress, GlobalAddress>;
  146. class ExportInstance {
  147. public:
  148. explicit ExportInstance(String name, ExternValue value)
  149. : m_name(move(name))
  150. , m_value(move(value))
  151. {
  152. }
  153. auto& name() const { return m_name; }
  154. auto& value() const { return m_value; }
  155. private:
  156. String m_name;
  157. ExternValue m_value;
  158. };
  159. class ModuleInstance {
  160. public:
  161. explicit ModuleInstance(
  162. Vector<FunctionType> types, Vector<FunctionAddress> function_addresses, Vector<TableAddress> table_addresses,
  163. Vector<MemoryAddress> memory_addresses, Vector<GlobalAddress> global_addresses, Vector<ExportInstance> exports)
  164. : m_types(move(types))
  165. , m_functions(move(function_addresses))
  166. , m_tables(move(table_addresses))
  167. , m_memories(move(memory_addresses))
  168. , m_globals(move(global_addresses))
  169. , m_exports(move(exports))
  170. {
  171. }
  172. ModuleInstance() = default;
  173. auto& types() const { return m_types; }
  174. auto& functions() const { return m_functions; }
  175. auto& tables() const { return m_tables; }
  176. auto& memories() const { return m_memories; }
  177. auto& globals() const { return m_globals; }
  178. auto& exports() const { return m_exports; }
  179. auto& types() { return m_types; }
  180. auto& functions() { return m_functions; }
  181. auto& tables() { return m_tables; }
  182. auto& memories() { return m_memories; }
  183. auto& globals() { return m_globals; }
  184. auto& exports() { return m_exports; }
  185. private:
  186. Vector<FunctionType> m_types;
  187. Vector<FunctionAddress> m_functions;
  188. Vector<TableAddress> m_tables;
  189. Vector<MemoryAddress> m_memories;
  190. Vector<GlobalAddress> m_globals;
  191. Vector<ExportInstance> m_exports;
  192. };
  193. class WasmFunction {
  194. public:
  195. explicit WasmFunction(const FunctionType& type, const ModuleInstance& module, const Module::Function& code)
  196. : m_type(type)
  197. , m_module(module)
  198. , m_code(code)
  199. {
  200. }
  201. auto& type() const { return m_type; }
  202. auto& module() const { return m_module; }
  203. auto& code() const { return m_code; }
  204. private:
  205. FunctionType m_type;
  206. const ModuleInstance& m_module;
  207. const Module::Function& m_code;
  208. };
  209. class HostFunction {
  210. public:
  211. explicit HostFunction(AK::Function<Result(Configuration&, Vector<Value>&)> function, const FunctionType& type)
  212. : m_function(move(function))
  213. , m_type(type)
  214. {
  215. }
  216. auto& function() { return m_function; }
  217. auto& type() const { return m_type; }
  218. private:
  219. AK::Function<Result(Configuration&, Vector<Value>&)> m_function;
  220. FunctionType m_type;
  221. };
  222. using FunctionInstance = Variant<WasmFunction, HostFunction>;
  223. class Reference {
  224. public:
  225. struct Null {
  226. ValueType type;
  227. };
  228. struct Func {
  229. FunctionAddress address;
  230. };
  231. struct Extern {
  232. ExternAddress address;
  233. };
  234. using RefType = Variant<Null, Func, Extern>;
  235. explicit Reference(RefType ref)
  236. : m_ref(move(ref))
  237. {
  238. }
  239. auto& ref() const { return m_ref; }
  240. private:
  241. RefType m_ref;
  242. };
  243. class TableInstance {
  244. public:
  245. explicit TableInstance(const TableType& type, Vector<Optional<Reference>> elements)
  246. : m_elements(move(elements))
  247. , m_type(type)
  248. {
  249. }
  250. auto& elements() const { return m_elements; }
  251. auto& elements() { return m_elements; }
  252. auto& type() const { return m_type; }
  253. private:
  254. Vector<Optional<Reference>> m_elements;
  255. const TableType& m_type;
  256. };
  257. class MemoryInstance {
  258. public:
  259. explicit MemoryInstance(const MemoryType& type)
  260. : m_type(type)
  261. {
  262. grow(m_type.limits().min() * Constants::page_size);
  263. }
  264. auto& type() const { return m_type; }
  265. auto size() const { return m_size; }
  266. auto& data() const { return m_data; }
  267. auto& data() { return m_data; }
  268. bool grow(size_t size_to_grow)
  269. {
  270. if (size_to_grow == 0)
  271. return true;
  272. auto new_size = m_data.size() + size_to_grow;
  273. if (m_type.limits().max().value_or(new_size) < new_size)
  274. return false;
  275. auto previous_size = m_size;
  276. m_data.grow(new_size);
  277. m_size = new_size;
  278. // The spec requires that we zero out everything on grow
  279. __builtin_memset(m_data.offset_pointer(previous_size), 0, size_to_grow);
  280. return true;
  281. }
  282. private:
  283. const MemoryType& m_type;
  284. size_t m_size { 0 };
  285. ByteBuffer m_data;
  286. };
  287. class GlobalInstance {
  288. public:
  289. explicit GlobalInstance(Value value, bool is_mutable)
  290. : m_mutable(is_mutable)
  291. , m_value(move(value))
  292. {
  293. }
  294. auto is_mutable() const { return m_mutable; }
  295. auto& value() const { return m_value; }
  296. void set_value(Value value)
  297. {
  298. VERIFY(is_mutable());
  299. m_value = move(value);
  300. }
  301. private:
  302. bool m_mutable { false };
  303. Value m_value;
  304. };
  305. class Store {
  306. public:
  307. Store() = default;
  308. Optional<FunctionAddress> allocate(ModuleInstance& module, const Module::Function& function);
  309. Optional<FunctionAddress> allocate(HostFunction&&);
  310. Optional<TableAddress> allocate(const TableType&);
  311. Optional<MemoryAddress> allocate(const MemoryType&);
  312. Optional<GlobalAddress> allocate(const GlobalType&, Value);
  313. FunctionInstance* get(FunctionAddress);
  314. TableInstance* get(TableAddress);
  315. MemoryInstance* get(MemoryAddress);
  316. GlobalInstance* get(GlobalAddress);
  317. private:
  318. Vector<FunctionInstance> m_functions;
  319. Vector<TableInstance> m_tables;
  320. Vector<MemoryInstance> m_memories;
  321. Vector<GlobalInstance> m_globals;
  322. };
  323. class Label {
  324. public:
  325. explicit Label(size_t arity, InstructionPointer continuation)
  326. : m_arity(arity)
  327. , m_continuation(continuation)
  328. {
  329. }
  330. auto continuation() const { return m_continuation; }
  331. auto arity() const { return m_arity; }
  332. private:
  333. size_t m_arity { 0 };
  334. InstructionPointer m_continuation;
  335. };
  336. class Frame {
  337. AK_MAKE_NONCOPYABLE(Frame);
  338. public:
  339. explicit Frame(const ModuleInstance& module, Vector<Value> locals, const Expression& expression, size_t arity)
  340. : m_module(module)
  341. , m_locals(move(locals))
  342. , m_expression(expression)
  343. , m_arity(arity)
  344. {
  345. }
  346. auto& module() const { return m_module; }
  347. auto& locals() const { return m_locals; }
  348. auto& locals() { return m_locals; }
  349. auto& expression() const { return m_expression; }
  350. auto arity() const { return m_arity; }
  351. private:
  352. const ModuleInstance& m_module;
  353. Vector<Value> m_locals;
  354. const Expression& m_expression;
  355. size_t m_arity { 0 };
  356. };
  357. class Stack {
  358. public:
  359. using EntryType = Variant<NonnullOwnPtr<Value>, NonnullOwnPtr<Label>, NonnullOwnPtr<Frame>>;
  360. Stack() = default;
  361. [[nodiscard]] bool is_empty() const { return m_data.is_empty(); }
  362. void push(EntryType entry) { m_data.append(move(entry)); }
  363. auto pop() { return m_data.take_last(); }
  364. auto& peek() const { return m_data.last(); }
  365. auto size() const { return m_data.size(); }
  366. auto& entries() const { return m_data; }
  367. private:
  368. Vector<EntryType> m_data;
  369. };
  370. using InstantiationResult = AK::Result<NonnullOwnPtr<ModuleInstance>, InstantiationError>;
  371. class AbstractMachine {
  372. public:
  373. explicit AbstractMachine() = default;
  374. // Load and instantiate a module, and link it into this interpreter.
  375. InstantiationResult instantiate(const Module&, Vector<ExternValue>);
  376. Result invoke(FunctionAddress, Vector<Value>);
  377. auto& store() const { return m_store; }
  378. auto& store() { return m_store; }
  379. private:
  380. Optional<InstantiationError> allocate_all(const Module&, ModuleInstance&, Vector<ExternValue>&, Vector<Value>& global_values);
  381. Store m_store;
  382. };
  383. class Linker {
  384. public:
  385. struct Name {
  386. String module;
  387. String name;
  388. ImportSection::Import::ImportDesc type;
  389. };
  390. explicit Linker(const Module& module)
  391. : m_module(module)
  392. {
  393. }
  394. // Link a module, the import 'module name' is ignored with this.
  395. void link(const ModuleInstance&);
  396. // Link a bunch of qualified values, also matches 'module name'.
  397. void link(const HashMap<Name, ExternValue>&);
  398. auto& unresolved_imports()
  399. {
  400. populate();
  401. return m_unresolved_imports;
  402. }
  403. AK::Result<Vector<ExternValue>, LinkError> finish();
  404. private:
  405. void populate();
  406. const Module& m_module;
  407. HashMap<Name, ExternValue> m_resolved_imports;
  408. HashTable<Name> m_unresolved_imports;
  409. Vector<Name> m_ordered_imports;
  410. Optional<LinkError> m_error;
  411. };
  412. }
  413. template<>
  414. struct AK::Traits<Wasm::Linker::Name> : public AK::GenericTraits<Wasm::Linker::Name> {
  415. static constexpr bool is_trivial() { return false; }
  416. static unsigned hash(const Wasm::Linker::Name& entry) { return pair_int_hash(entry.module.hash(), entry.name.hash()); }
  417. static bool equals(const Wasm::Linker::Name& a, const Wasm::Linker::Name& b) { return a.name == b.name && a.module == b.module; }
  418. };