wasm虛擬機相關接口定義實現

1、執行流程

controller::push_transaction()  // 事務

  -> transaction_context::exec()  // 事務

    -> transaction_context::dispatch_action() // 通過便利transaction中的各個action來分發執行

      -> apply_context::exec() // action

        -> apply_context::exec_one() // action 執行具體的智能合約

          -> controller::get_wasm_interface()->apply() // 進入虛擬機開始執行對應智能合約

            -> wasm_interface_impl::get_instantiated_module()->apply() // 加載智能合約並執行

              -> wavm_instantiated_module::apply() // 具體模塊開始接收調用

                -> wavm_instantiated_module::call() // 開始執行具體函數

                  -> Runtime::invokeFunction() // 進入到wasm運行時庫開始執行具體函數

2、接口定義

wasm_interface_impl wasm虛擬機實現類

2.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();

  ...

 

  

}
wasm_eosio_injection wasm虛擬機注入
默認通過內存計算
using standard_module_injectors = module_injectors<max_memory_injection_visitor>
max_memory_injection_visitor 最大內存攔截
監控模塊適用內存數

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.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);

}

wasm_instantiated_module_interface wasm模塊基類
wavm_instantiated_module wavm模塊實現類
wavm_instantiated_module wavm模塊實現類
// 函數執行

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);

  }

 

}

wabt_instantiated_module wabt模塊
整體實現過程同wavm,局部有差異

3、虛擬機啓動

controller_impl 控制器實現類
在controller構造函數中構建wasm_interface對象

controller_impl( const controller::config& cfg, controller& s  )

...略...

  wasmif( cfg.wasm_runtime ), //根據配置來構建wasm_interface對象

...略...

《轉自wasm虛擬機》

《eos智能合約與主進程交互》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章