Skip to content

Commit

Permalink
[Component] share loading entry for component and module (#2945)
Browse files Browse the repository at this point in the history
* loading entry share component & module

Signed-off-by: Lîm Tsú-thuàn <dannypsnl@secondstate.io>

* share the same loading entry

Signed-off-by: Lîm Tsú-thuàn <dannypsnl@secondstate.io>

* the missing validation for the prototype

Signed-off-by: Lîm Tsú-thuàn <dannypsnl@secondstate.io>

* replace loadModule with loadWasmUnit

leave an error message for future component model validating & instantiation

Signed-off-by: Lîm Tsú-thuàn <dannypsnl@secondstate.io>

* move to a proper location of the module's AOT section

Signed-off-by: Lîm Tsú-thuàn <dannypsnl@secondstate.io>

* set the actual version

Signed-off-by: Lîm Tsú-thuàn <dannypsnl@secondstate.io>

* setup unsafe run component for future work

Signed-off-by: Lîm Tsú-thuàn <dannypsnl@secondstate.io>

* remove shadowing

Signed-off-by: Lîm Tsú-thuàn <dannypsnl@secondstate.io>

---------

Signed-off-by: Lîm Tsú-thuàn <dannypsnl@secondstate.io>
  • Loading branch information
dannypsnl committed Nov 3, 2023
1 parent f7931f2 commit d5023b7
Show file tree
Hide file tree
Showing 11 changed files with 407 additions and 223 deletions.
23 changes: 23 additions & 0 deletions include/ast/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,29 @@
namespace WasmEdge {
namespace AST {

class Component {
public:
/// Getter of magic vector.
const std::vector<Byte> &getMagic() const noexcept { return Magic; }
std::vector<Byte> &getMagic() noexcept { return Magic; }

/// Getter of version vector.
const std::vector<Byte> &getVersion() const noexcept { return Version; }
std::vector<Byte> &getVersion() noexcept { return Version; }

/// Getter of layer vector.
const std::vector<Byte> &getLayer() const noexcept { return Layer; }
std::vector<Byte> &getLayer() noexcept { return Layer; }

private:
/// \name Data of Module node.
/// @{
std::vector<Byte> Magic;
std::vector<Byte> Version;
std::vector<Byte> Layer;
/// @}
};

/// AST Module node.
class Module {
public:
Expand Down
1 change: 1 addition & 0 deletions include/common/enum.inc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifdef UseASTNodeAttr
#define A Line

A(Component, "component")
A(Module, "module")
A(Sec_Custom, "custom section")
A(Sec_Type, "type section")
Expand Down
20 changes: 19 additions & 1 deletion include/loader/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ class Loader {
static Expect<std::vector<Byte>>
loadFile(const std::filesystem::path &FilePath);

Expect<std::variant<AST::Component, AST::Module>>
parseWasmUnit(const std::filesystem::path &FilePath);
Expect<std::variant<AST::Component, AST::Module>>
parseWasmUnit(Span<const uint8_t> Code);

/// Parse component from file path.
Expect<std::unique_ptr<AST::Component>>
parseComponent(const std::filesystem::path &FilePath);

/// Parse component from byte code.
Expect<std::unique_ptr<AST::Component>>
parseComponent(Span<const uint8_t> Code);

/// Parse module from file path.
Expect<std::unique_ptr<AST::Module>>
parseModule(const std::filesystem::path &FilePath);
Expand Down Expand Up @@ -125,14 +138,19 @@ class Loader {
Expect<void> checkInstrProposals(OpCode Code, uint64_t Offset) const noexcept;
/// @}

Expect<std::variant<AST::Component, AST::Module>> loadUnit();

/// \name Load AST Module functions
/// @{
Expect<std::unique_ptr<AST::Module>> loadModule();
Expect<void> loadModule(AST::Module &Mod);
Expect<void> loadCompiled(AST::Module &Mod);
/// @}

/// \name Load AST section node helper functions
/// @{
Expect<void> loadUniversalWASM(AST::Module &Mod);
Expect<void> loadModuleAOT(AST::AOTSection &AOTSection);

Expect<uint32_t> loadSectionSize(ASTNodeAttr Node);
template <typename T, typename L>
Expect<void> loadSectionContent(T &Sec, L &&Func) {
Expand Down
2 changes: 2 additions & 0 deletions include/validator/validator.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class Validator {
Validator(const Configure &Conf) noexcept : Conf(Conf) {}
~Validator() noexcept = default;

/// Validate AST::Component.
Expect<void> validate(const AST::Component &Comp);
/// Validate AST::Module.
Expect<void> validate(const AST::Module &Mod);

Expand Down
4 changes: 4 additions & 0 deletions include/vm/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ class VM {
unsafeRunWasmFile(const AST::Module &Module, std::string_view Func,
Span<const ValVariant> Params = {},
Span<const ValType> ParamTypes = {});
Expect<std::vector<std::pair<ValVariant, ValType>>>
unsafeRunWasmFile(const AST::Component &Component, std::string_view Func,
Span<const ValVariant> Params = {},
Span<const ValType> ParamTypes = {});

Expect<void> unsafeLoadWasm(const std::filesystem::path &Path);
Expect<void> unsafeLoadWasm(Span<const Byte> Code);
Expand Down
1 change: 1 addition & 0 deletions lib/loader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ if(NOT WIN32)
endif()

wasmedge_add_library(wasmedgeLoader
ast/component.cpp
ast/module.cpp
ast/section.cpp
ast/description.cpp
Expand Down
85 changes: 85 additions & 0 deletions lib/loader/ast/component.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2019-2022 Second State INC

#include "loader/loader.h"

#include <bitset>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>

namespace WasmEdge {
namespace Loader {

Expect<std::variant<AST::Component, AST::Module>> Loader::loadUnit() {
// component ::= <preamble> s*:<section>* => (component flatten(s*))
// preamble ::= <magic> <version> <layer>
// magic ::= 0x00 0x61 0x73 0x6D
// version ::= 0x0a 0x00
// layer ::= 0x01 0x00

// The combination of version and layer is corresponding to the version of
// core wasm.
// The core module has same magic but the different version:
// 0x01 0x00 0x00 0x00
auto Magic = FMgr.readBytes(4);
if (!Magic) {
return logLoadError(Magic.error(), FMgr.getLastOffset(),
ASTNodeAttr::Component);
}
std::vector<Byte> WasmMagic = {0x00, 0x61, 0x73, 0x6D};
if (*Magic != WasmMagic) {
return logLoadError(ErrCode::Value::MalformedMagic, FMgr.getLastOffset(),
ASTNodeAttr::Component);
}
auto Ver = FMgr.readBytes(4);
if (!Ver) {
return logLoadError(Ver.error(), FMgr.getLastOffset(),
ASTNodeAttr::Component);
}
std::vector<Byte> ModuleVersion = {0x01, 0x00, 0x00, 0x00};
// spec says 0x0a, but it's actually 0x0d, where cargo component compiled out
std::vector<Byte> ComponentVersion = {0x0d, 0x00, 0x01, 0x00};
if (*Ver == ModuleVersion) {
auto Mod = std::make_unique<AST::Module>();
Mod->getMagic() = WasmMagic;
Mod->getVersion() = *Ver;
if (!Conf.getRuntimeConfigure().isForceInterpreter()) {

if (auto Res = loadModuleAOT(Mod->getAOTSection()); !Res) {
return Unexpect(Res);
}
}
// Seek to the position after the binary header.
FMgr.seek(8);
if (auto Res = loadModule(*Mod); !Res) {
return Unexpect(Res);
}

// Load library from AOT Section for the universal WASM case.
// For the force interpreter mode, skip this.
if (!Conf.getRuntimeConfigure().isForceInterpreter() &&
WASMType == InputType::UniversalWASM) {
if (auto Res = loadUniversalWASM(*Mod); !Res) {
return Unexpect(Res);
}
}
return *Mod;
} else if (*Ver == ComponentVersion) {
auto Comp = std::make_unique<AST::Component>();
Comp->getMagic() = WasmMagic;
Comp->getVersion() = {(*Ver)[0], (*Ver)[1]};
Comp->getLayer() = {(*Ver)[2], (*Ver)[3]};
spdlog::error("Component model is not fully parsed yet!");
return *Comp;
} else {
return logLoadError(ErrCode::Value::MalformedVersion, FMgr.getLastOffset(),
ASTNodeAttr::Component);
}
}

} // namespace Loader
} // namespace WasmEdge
Loading

0 comments on commit d5023b7

Please sign in to comment.