wasm虛擬機相關接口定義實現web
執行流程app
controller::push_transaction() // 事務ide
-> transaction_context::exec() // 事務函數
-> transaction_context::dispatch_action() // 經過便利transaction中的各個action來分發執行ui
-> apply_context::exec() // actionspa
-> apply_context::exec_one() // action 執行具體的智能合約code
-> controller::get_wasm_interface()->apply() // 進入虛擬機開始執行對應智能合約對象
-> wasm_interface_impl::get_instantiated_module()->apply() // 加載智能合約並執行接口
-> wavm_instantiated_module::apply() // 具體模塊開始接收調用事務
-> wavm_instantiated_module::call() // 開始執行具體函數
-> Runtime::invokeFunction() // 進入到wasm運行時庫開始執行具體函數
接口定義
1.加載模塊實現
std::unique_ptr<wasm_instantiated_module_interface> &get_instantiated_module(const digest_type &code_id,const shared_string &code,transaction_context &trx_context)
{
...
IR::Module module;
try
{
// 將模塊序列化到內存並加載模塊
Serialization::MemoryInputStream stream((const U8 *)code.data(), code.size());
WASM::serialize(stream, module);
module.userSections.clear();
}
catch(...){
...
}
...
/**
* 這裏是注入攔截代碼,用於攔截計算相應cpu和內存數據
*/
wasm_injections::wasm_binary_injection injector(module); //以下
injector.inject();
...
}
監控模塊適用內存數
void max_memory_injection_visitor::inject( Module& m ) {
if(m.memories.defs.size() && m.memories.defs[0].type.size.max > maximum_linear_memory/wasm_page_size)
m.memories.defs[0].type.size.max = maximum_linear_memory/wasm_page_size;
}
2.執行智能合約
void wasm_interface::apply(const digest_type &code_id, const shared_string &code, apply_context &context)
{
// 智能合約虛擬機加載模塊
// 加載模塊時會經過以下的injection來注入監控
// 默認:eos監控最大使用內存:max_memory_injection_visitor
// 經過apply來執行相應智能合約
my->get_instantiated_module(code_id, code, context.trx_context)->apply(context);
}
// 函數執行
void apply(apply_context& context) override {
// 默認3個參數
// receiver/account/name
// 其餘參數經過context獲取
vector<Value> args = {Value(uint64_t(context.receiver)),
Value(uint64_t(context.act.account)),
Value(uint64_t(context.act.name))};
call("apply", args, context);
}
void call(const string &entry_point, const vector <Value> &args, apply_context &context) {
try {
FunctionInstance* call = asFunctionNullable(getInstanceExport(_instance,entry_point));
if( !call )
return;
the_running_instance_context.memory = default_mem;
the_running_instance_context.apply_ctx = &context;
// 加載instance
resetGlobalInstances(_instance);
// 調用初始化函數
runInstanceStartFunc(_instance);
// 這裏就調用到了wasm runtime來調用智能合約
Runtime::invokeFunction(call,args);
}
}
總體實現過程同wavm,局部有差別
虛擬機啓動
在controller構造函數中構建wasm_interface對象
controller_impl( const controller::config& cfg, controller& s )
...略...
wasmif( cfg.wasm_runtime ), //根據配置來構建wasm_interface對象
...略...