2014-03-07 24 views
0

此代碼在Firefox中很好地工作 - 儘管由於某些原因,將Uint8Array更改爲Uint32array會中斷。在這種情況下,我需要以不同的方式強制數字嗎?爲什麼我不能在ASM.js中使用32位ints數組?

function Module(stdlib, foreign, heap) { 
     "use asm"; 

     // Variable Declarations 
     var els = new stdlib.Uint8Array(heap); 

     // Function Declarations 
     function firstn(x) { 
      x = x|0 //32-bit (int) 
      var i=0; 
      for (; (i|0) < (x|0); i = (i+1)|0) { 
       els[i] = i; 
      } 
     } 

     return { firstn: firstn }; 
    } 

    buf = ArrayBuffer(1024*8) 

    f = Module(window,{},buf).firstn; 
    f(5) 
    console.log(new Uint8Array(buf)); 

還有一件事 - 這可能發送arraybuffer,並有它產生的最終數組的引用,用C++ emscriptem編譯asm.js嗎?

+0

究竟是什麼突破?你在更改Uint32Array中的哪兩個Uint8Array callites?或者你是否改變了他們? –

+0

當我將Uint8Arrays更改爲Uint32Arrays時,它不會編譯 - 可能是由於需要使用不同的類型。 – NoBugs

回答

1

它看起來像asm.js只允許使用表單(foo >> 2)的表達式索引到Int32Array或Uint32Array,儘管我在規範中找不到任何對此的引用。也就是說,它假設你所擁有的是一個地址,並試圖在該地址查找整數。我想這是有道理的,因爲C代碼像這樣有點:

int32_t arr[5]; 
arr[i]; 

會得到編譯成機器代碼,不會的*((char*)arr + 4*i)相當於...不管怎樣,在你的代碼替換els[i] = i

els[(i<<2)>>2] = i; 

似乎使事情與Uint32Array工作。

+0

謝謝!這很好,你是怎麼發現的?我沒有看到它是如何加倍和減半的 - 解決了奇怪的是,當我使用斐波納契計算時,它不起作用:'els [(i = 1到2)=(els [((i - 1) <<2)>> 2] + els [((i-2)<<2)>> 2])| 0' – NoBugs

+0

我通過查找http://mxr.mozilla.org/mozilla-central/source/中涉及的驗證錯誤消息js/src/jit/AsmJS.cpp,然後讀取周圍的代碼。我不知道用戶友好的過程。至於斐波那契,看起來你需要將數組讀取的結果明確地轉換爲int,就像這樣:[els [((i-1)<< 2) >> 2] | 0)+(els [((i-2)<< 2) >> 2] | 0);'。我是不知道爲什麼它不能假定一個Uint32Array讀取鍵入「無符號」;它認爲該類型是「intish」。 –

相關問題