提交 31d2be18 编写于 作者: Y YiYing He 提交者: hydai

[Runtime] Use std::variant to save space in function instance.

上级 74e9a3d8
......@@ -28,61 +28,91 @@ public:
using CompiledFunction = void;
FunctionInstance() = delete;
/// Move constructor.
FunctionInstance(FunctionInstance &&Inst) noexcept
: ModuleAddr(Inst.ModuleAddr), FuncType(Inst.FuncType),
Data(std::move(Inst.Data)) {}
/// Constructor for native function.
FunctionInstance(const uint32_t ModAddr, const FType &Type,
Span<const std::pair<uint32_t, ValType>> Locs,
AST::InstrView Expr)
: IsHostFunction(false), FuncType(Type), ModuleAddr(ModAddr),
Locals(Locs.begin(), Locs.end()), Instrs(Expr.begin(), Expr.end()) {}
AST::InstrView Expr) noexcept
: ModuleAddr(ModAddr), FuncType(Type),
Data(std::in_place_type_t<WasmFunction>(), Locs, Expr) {}
/// Constructor for compiled function.
FunctionInstance(const uint32_t ModAddr, const FType &Type,
Loader::Symbol<CompiledFunction> S) noexcept
: ModuleAddr(ModAddr), FuncType(Type),
Data(std::in_place_type_t<Loader::Symbol<CompiledFunction>>(),
std::move(S)) {}
/// Constructor for host function. Module address will not be used.
FunctionInstance(std::unique_ptr<HostFunctionBase> &&Func)
: IsHostFunction(true), FuncType(Func->getFuncType()), ModuleAddr(0),
HostFunc(std::move(Func)) {}
FunctionInstance(std::unique_ptr<HostFunctionBase> &&Func) noexcept
: ModuleAddr(0), FuncType(Func->getFuncType()),
Data(std::in_place_type_t<std::unique_ptr<HostFunctionBase>>(),
std::move(Func)) {}
virtual ~FunctionInstance() = default;
/// Getter of checking is native wasm function.
bool isWasmFunction() const {
return std::holds_alternative<WasmFunction>(Data);
}
/// Getter of checking is compiled function.
bool isCompiledFunction() const {
return std::holds_alternative<Loader::Symbol<CompiledFunction>>(Data);
}
/// Getter of checking is host function.
bool isHostFunction() const { return IsHostFunction; }
bool isHostFunction() const {
return std::holds_alternative<std::unique_ptr<HostFunctionBase>>(Data);
}
/// Getter of module address of this function instance.
uint32_t getModuleAddr() const { return ModuleAddr; }
/// Setter of module address of this function instance.
void setModuleAddr(const uint32_t Addr) { ModuleAddr = Addr; }
/// Getter of function type.
const FType &getFuncType() const { return FuncType; }
/// Getter of function body instrs.
Span<const std::pair<uint32_t, ValType>> getLocals() const { return Locals; }
/// Getter of function local variables.
Span<const std::pair<uint32_t, ValType>> getLocals() const noexcept {
return std::get_if<WasmFunction>(&Data)->Locals;
}
/// Getter of function body instrs.
AST::InstrView getInstrs() const { return Instrs; }
AST::InstrView getInstrs() const noexcept {
if (std::holds_alternative<WasmFunction>(Data)) {
return std::get<WasmFunction>(Data).Instrs;
} else {
return {};
}
}
/// Getter of symbol
const auto getSymbol() const noexcept { return Symbol; }
/// Setter of symbol
void setSymbol(Loader::Symbol<CompiledFunction> S) noexcept {
Symbol = std::move(S);
const auto getSymbol() const noexcept {
return *std::get_if<Loader::Symbol<CompiledFunction>>(&Data);
}
/// Getter of host function.
HostFunctionBase &getHostFunc() const { return *HostFunc.get(); }
HostFunctionBase &getHostFunc() const {
return *std::get_if<std::unique_ptr<HostFunctionBase>>(&Data)->get();
}
private:
const bool IsHostFunction;
const FType &FuncType;
/// \name Data of function instance for native function.
struct WasmFunction {
const std::vector<std::pair<uint32_t, ValType>> Locals;
const AST::InstrVec Instrs;
WasmFunction(Span<const std::pair<uint32_t, ValType>> Locs,
AST::InstrView Expr) noexcept
: Locals(Locs.begin(), Locs.end()), Instrs(Expr.begin(), Expr.end()) {}
};
/// \name Data of function instance.
/// @{
uint32_t ModuleAddr;
const std::vector<std::pair<uint32_t, ValType>> Locals;
const AST::InstrVec Instrs;
Loader::Symbol<CompiledFunction> Symbol;
/// @}
/// \name Data of function instance for host function.
/// @{
std::unique_ptr<HostFunctionBase> HostFunc;
const uint32_t ModuleAddr;
const FType &FuncType;
std::variant<WasmFunction, Loader::Symbol<CompiledFunction>,
std::unique_ptr<HostFunctionBase>>
Data;
/// @}
};
......
......@@ -62,7 +62,7 @@ Interpreter::enterFunction(Runtime::StoreManager &StoreMgr,
}
/// For host function case, the continuation will be the next.
return From + 1;
} else if (auto CompiledFunc = Func.getSymbol()) {
} else if (Func.isCompiledFunction()) {
auto Wrapper = Func.getFuncType().getSymbol();
/// Compiled function case: Push frame with locals and args.
const size_t ArgsN = FuncType.Params.size();
......@@ -89,7 +89,8 @@ Interpreter::enterFunction(Runtime::StoreManager &StoreMgr,
const int Status = sigsetjmp(*TrapJump, true);
if (Status == 0) {
SignalEnabler Enabler;
Wrapper(&ExecutionContext, CompiledFunc.get(), Args.data(), Rets.data());
Wrapper(&ExecutionContext, Func.getSymbol().get(), Args.data(),
Rets.data());
}
TrapJump = std::move(OldTrapJump);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册