Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce the Store + fixes to validation (#495)
Closes #486 Introduces the Store abstraction and adopts it in the test cases, cleaning up a lot of unnecessary test cases. ~~I am opening the PR in draft, as it needs rebasing anyway.~~ The change is relatively simple, it introduces the `Store` as described in #486, with a fluent interface of the type: ```java var store = new Store() .addFunctions(f1, ...) .addGlobals(g1, ...) ``` This API is copied over from `HostImports`, although this is not a subclass; it is still "related" to it; in fact: - it is possible to get the contents of a store ("converting" it, if you will) to a `HostImports` instance with `store.toHostImports()`; - the `Store` also accepts an entire `HostImports` instance as a shorthand for registering all of the items in it with `store.addHostImports(hostImports)` It also provides shorthands to register all of the exports in a module as qualified "HostGlobal"s, "HostFunction"s etc. ```java store.register("name", instance); // now each export `e` in instance, is stored as the qualified name `name.e` ``` It is also possible to instantiate and register in one move: ```java var instance = store.instantiate("name", module); ``` this is equivalent to: ```java var instance = Instance.builder(module).withHostImports(store.toHostImports()).build() store.register("name", instance) ``` The Store is deterministic, in that its behavior is known: when clashing instances (i.e. where their qualified name `n.e` is clashing) are registered to the store, the latest registration overwrites the oldest. Internally each type(*) (globals, funcs, etc) is kept in separate LinkedHashMaps. Introducing the `Store` enormously simplifies the definition of the spec tests, because such tests actually expect changes to "stick" across cases; i.e. they mutate sequentially a shared `store` instance adding and updating memories, functions, globals, tables. In fact, introducing the store highlighted a bunch of issues with validation, that I am fixing contextually: even though we would not let any invalid instance slip, we would raise `UnlinkableException`s during the initialization of the instance, instead of throwing an `InvalidException` at validation time. Potentially this allows us to avoid the second check at the time of instantiation, because we could assume that validation has passed. (*) note: this actually means that clashes might exists if two different types have the same qualified name 🤔 e.g. `n.e` is a func, but there is also a `n.e` that is a global 🤔 --------- Signed-off-by: Edoardo Vacchi <[email protected]> Co-authored-by: Andrea Peruffo <[email protected]>
- Loading branch information