2017-04-26 73 views
0

不幸的是,我無法獲得一個工作工具鏈來將C/C++編譯成一個wasm文件,但我希望有一個靈魂能夠幫助我。給定程序片段:指向本地結構的指針如何轉換爲webassembly?

struct foo { 
    int a; 
    float b; 
}; 

void function(foo * p); 

void my_program() { 
    struct foo my_foo; 
    my_foo.a = 1; 
    my_foo.b = -3.0F; 
    foo(&my_foo); 
} 

my_program的主界面代碼是什麼樣的?

回答

2

我打算假設你的意思是什麼文本格式看起來像?

我調整了兩件事情在你的代碼,以便它編譯:

struct foo { 
    int a; 
    float b; 
}; 

extern void bar(struct foo * p); 

void my_program() { 
    struct foo my_foo; 
    my_foo.a = 1; 
    my_foo.b = -3.0F; 
    bar(&my_foo); 
} 

使用emscripten/binaryen編譯它,然後使用wasm2wast:

emcc -s WASM=1 -s SIDE_MODULE=1 -O2 str.c -o str.js 
wasm-dis str.wasm -o str.wast 

注意,如果沒有-s SIDE_MODULE=1 -O2,emscripten拉入一堆標準庫(malloc等),並且wast文件長達10,000行。我假設你可能只是想要沒有所有鏈接/包含的相當簡單的結論/結果。

導致以下赤身文件:

(module 
(type $0 (func (param i32))) 
(type $1 (func)) 
(import "env" "memoryBase" (global $import$0 i32)) 
(import "env" "_bar" (func $import$1 (param i32))) 
(import "env" "memory" (memory $0 256)) 
(import "env" "table" (table 0 anyfunc)) 
(import "env" "tableBase" (global $import$4 i32)) 
(global $global$0 (mut i32) (i32.const 0)) 
(global $global$1 (mut i32) (i32.const 0)) 
(export "_my_program" (func $0)) 
(export "__post_instantiate" (func $2)) 
(export "runPostSets" (func $1)) 
(func $0 (type $1) 
    (local $var$0 i32) 
    (local $var$1 i32) 
    (block $label$0 
    (set_local $var$0 
    (get_global $global$0) 
    ) 
    (set_global $global$0 
    (i32.add 
    (get_global $global$0) 
    (i32.const 16) 
    ) 
    ) 
    (i32.store 
    (tee_local $var$1 
    (get_local $var$0) 
    ) 
    (i32.const 1) 
    ) 
    (f32.store offset=4 
    (get_local $var$1) 
    (f32.const -3) 
    ) 
    (call $import$1 
    (get_local $var$1) 
    ) 
    (set_global $global$0 
    (get_local $var$0) 
    ) 
) 
) 
(func $1 (type $1) 
    (nop) 
) 
(func $2 (type $1) 
    (block $label$0 
    (set_global $global$0 
    (get_global $import$0) 
    ) 
    (set_global $global$1 
    (i32.add 
    (get_global $global$0) 
    (i32.const 5242880) 
    ) 
    ) 
    (call $1) 
) 
) 
;; custom section "dylink", size 5 
) 

注意memoryBasetableBase__post_instantiaterunPostSets被emscripten爲平臺整合內存/初始化增加。 memoryBase基本上是C堆棧的開始,並且該值被__post_instantiate複製到$global$0(這對此模塊中的所有功能都是全局的)。當調用my_program時,首先發生的是我們將堆棧指針調整爲16,指向編譯器爲堆棧上的my_foo結構「分配」空間的位置。我們現在使用offset=X執行一些i32.store操作來更新foo中的字段。當函數返回時,我們將堆棧指針($global$0)恢復到我們輸入函數時的位置。

+0

我想了解的是如何分配本地存儲來爲結構提供空間。看起來全局2就像某種明確的堆棧指針一樣行事;它被複制到本地0中,增加16('sizeof foo')並且在過程退出時,它被重置回本地0的值。假設環境提供「堆棧指針」作爲全局指針,是否正確? –

+0

@JohnKällén是的,這是我的理解。我用binaryen更新了wasm-dis,因爲它具有更多的智能反彙編和更多註釋。我還爲代碼解釋說明了一些解釋性文字。 – kanaka

相關問題