<mark id="n9zld"></mark>

      <thead id="n9zld"><video id="n9zld"></video></thead>

      <ins id="n9zld"></ins>

        <b id="n9zld"></b>

            <font id="n9zld"><video id="n9zld"></video></font>
            <b id="n9zld"></b>

              <dfn id="n9zld"><video id="n9zld"></video></dfn>

                asm.js 和 Emscripten 入門教程

                作者: 阮一峰

                日期: 2017年9月 7日

                騰訊課堂 NEXT 學院

                Web 技術突飛猛進,但是有一個領域一直無法突破 ---- 游戲。

                游戲的性能要求非常高,一些大型游戲連 PC 跑起來都很吃力,更不要提在瀏覽器的沙盒模型里跑了!但是,盡管很困難,許多開發者始終沒放棄,希望讓瀏覽器運行 3D 游戲。

                2012年,Mozilla 的工程師 Alon Zakai 在研究 LLVM 編譯器時突發奇想:許多 3D 游戲都是用 C / C++ 語言寫的,如果能將 C / C++ 語言編譯成 JavaScript 代碼,它們不就能在瀏覽器里運行了嗎?眾所周知,JavaScript 的基本語法與 C 語言高度相似。

                于是,他開始研究怎么才能實現這個目標,為此專門做了一個編譯器項目 Emscripten。這個編譯器可以將 C / C++ 代碼編譯成 JS 代碼,但不是普通的 JS,而是一種叫做 asm.js 的 JavaScript 變體。

                本文就將介紹 asm.js 和 Emscripten 的基本用法,介紹如何將 C / C++ 轉成 JS。

                一、asm.js 的簡介

                1.1 原理

                C / C++ 編譯成 JS 有兩個最大的困難。

                • C / C++ 是靜態類型語言,而 JS 是動態類型語言。
                • C / C++ 是手動內存管理,而 JS 依靠垃圾回收機制。

                asm.js 就是為了解決這兩個問題而設計的:它的變量一律都是靜態類型,并且取消垃圾回收機制。除了這兩點,它與 JavaScript 并無差異,也就是說,asm.js 是 JavaScript 的一個嚴格的子集,只能使用后者的一部分語法。

                一旦 JavaScript 引擎發現運行的是 asm.js,就知道這是經過優化的代碼,可以跳過語法分析這一步,直接轉成匯編語言。另外,瀏覽器還會調用 WebGL 通過 GPU 執行 asm.js,即 asm.js 的執行引擎與普通的 JavaScript 腳本不同。這些都是 asm.js 運行較快的原因。據稱,asm.js 在瀏覽器里的運行速度,大約是原生代碼的50%左右。

                下面就依次介紹 asm.js 的兩大語法特點。

                1.2 靜態類型的變量

                asm.js 只提供兩種數據類型

                • 32位帶符號整數
                • 64位帶符號浮點數

                其他數據類型,比如字符串、布爾值或者對象,asm.js 一概不提供。它們都是以數值的形式存在,保存在內存中,通過 TypedArray 調用。

                如果變量的類型要在運行時確定,asm.js 就要求事先聲明類型,并且不得改變,這樣就節省了類型判斷的時間。

                asm.js 的類型聲明有固定寫法,變量 | 0表示整數,+變量表示浮點數。

                
                var a = 1;
                
                var x = a | 0;  // x 是32位整數
                var y = +a;  // y 是64位浮點數
                

                上面代碼中,變量x聲明為整數,y聲明為浮點數。支持 asm.js 的引擎一看到x = a | 0,就知道x是整數,然后采用 asm.js 的機制處理。如果引擎不支持 asm.js 也沒關系,這段代碼照樣可以運行,最后得到的還是同樣的結果。

                再看下面的例子。

                
                // 寫法一
                var first = 5;
                var second = first;
                
                // 寫法二
                var first = 5;
                var second = first | 0;
                

                上面代碼中,寫法一是普通的 JavaScript,變量second只有在運行時才能知道類型,這樣就很慢了,寫法二是 asm.js,second在聲明時就知道是整數,速度就提高了。

                函數的參數和返回值,都要用這種方式指定類型。

                
                function add(x, y) {
                  x = x | 0;
                  y = y | 0;
                  return (x + y) | 0;
                }
                

                上面代碼中,除了參數xy需要聲明類型,函數的返回值也需要聲明類型。

                1.3 垃圾回收機制

                asm.js 沒有垃圾回收機制,所有內存操作都由程序員自己控制。asm.js 通過 TypedArray 直接讀寫內存。

                下面就是直接讀寫內存的例子。

                
                var buffer = new ArrayBuffer(32768);
                var HEAP8 = new Int8Array(buffer);
                function compiledCode(ptr) {
                  HEAP[ptr] = 12;
                  return HEAP[ptr + 4];
                }  
                

                如果涉及到指針,也是一樣處理。

                
                size_t strlen(char *ptr) {
                  char *curr = ptr;
                  while (*curr != 0) {
                    curr++;
                  }
                  return (curr - ptr);
                }
                

                上面的代碼編譯成 asm.js,就是下面這樣。

                
                function strlen(ptr) {
                  ptr = ptr|0;
                  var curr = 0;
                  curr = ptr;
                  while (MEM8[curr]|0 != 0) {
                    curr = (curr + 1)|0;
                  }
                  return (curr - ptr)|0;
                }
                

                1.4 asm.js 與 WebAssembly 的異同

                如果你對 JS 比較了解,可能知道還有一種叫做 WebAssembly 的技術,也能將 C / C++ 轉成 JS 引擎可以運行的代碼。那么它與 asm.js 有何區別呢?

                回答是,兩者的功能基本一致,就是轉出來的代碼不一樣:asm.js 是文本,WebAssembly 是二進制字節碼,因此運行速度更快、體積更小。從長遠來看,WebAssembly 的前景更光明。

                但是,這并不意味著 asm.js 肯定會被淘汰,因為它有兩個優點:首先,它是文本,人類可讀,比較直觀;其次,所有瀏覽器都支持 asm.js,不會有兼容性問題。

                二、 Emscripten 編譯器

                2.1 Emscripten 簡介

                雖然 asm.js 可以手寫,但是它從來就是編譯器的目標語言,要通過編譯產生。目前,生成 asm.js 的主要工具是 Emscripten

                Emscripten 的底層是 LLVM 編譯器,理論上任何可以生成 LLVM IR(Intermediate Representation)的語言,都可以編譯生成 asm.js。 但是實際上,Emscripten 幾乎只用于將 C / C++ 代碼編譯生成 asm.js。

                
                C/C++ ? LLVM ==> LLVM IR ? Emscripten ? asm.js
                

                2.2 Emscripten 的安裝

                Emscripten 的安裝可以根據官方文檔。由于依賴較多,安裝起來比較麻煩,我發現更方便的方法是安裝 SDK

                你可以按照下面的步驟操作。

                
                $ git clone https://github.com/juj/emsdk.git
                $ cd emsdk
                $ ./emsdk install --build=Release sdk-incoming-64bit binaryen-master-64bit
                $ ./emsdk activate --build=Release sdk-incoming-64bit binaryen-master-64bit
                $ source ./emsdk_env.sh
                

                注意,最后一行非常重要。每次重新登陸或者新建 Shell 窗口,都要執行一次這行命令source ./emsdk_env.sh

                2.3 Hello World

                首先,新建一個最簡單的 C++ 程序hello.cc

                
                #include <iostream>
                
                int main() {
                  std::cout << "Hello World!" << std::endl;
                }
                

                然后,將這個程序轉成 asm.js。

                
                $ emcc hello.cc
                $ node a.out.js
                Hello World!
                

                上面代碼中,emcc命令用于編譯源碼,默認生成a.out.js。使用 Node 執行a.out.js,就會在命令行輸出 Hello World。

                注意,asm.js 默認自動執行main函數。

                emcc是 Emscripten 的編譯命令。它的用法非常簡單。

                
                # 生成 a.out.js
                $ emcc hello.c
                
                # 生成 hello.js
                $ emcc hello.c -o hello.js
                
                # 生成 hello.html 和 hello.js
                $ emcc hello.c -o hello.html
                

                三、Emscripten 語法

                3.1 C/C++ 調用 JavaScript

                Emscripten 允許 C / C++ 代碼直接調用 JavaScript。

                新建一個文件example1.cc,寫入下面的代碼。

                
                #include <emscripten.h>
                
                int main() {
                  EM_ASM({ alert('Hello World!'); });
                }
                

                EM_ASM是一個宏,會調用嵌入的 JavaScript 代碼。注意,JavaScript 代碼要寫在大括號里面。

                然后,將這個程序編譯成 asm.js。

                
                $ emcc example1.cc -o example1.html
                

                瀏覽器打開example1.html,就會跳出對話框Hello World!

                3.2 C/C++ 與 JavaScript 的通信

                Emscripten 允許 C / C++ 代碼與 JavaScript 通信。

                新建一個文件example2.cc,寫入下面的代碼。

                
                #include <emscripten.h>
                #include <iostream>
                
                int main() {
                  int val1 = 21;
                  int val2 = EM_ASM_INT({ return $0 * 2; }, val1);
                
                  std::cout << "val2 == " << val2 << std::endl;
                }
                

                上面代碼中,EM_ASM_INT表示 JavaScript 代碼返回的是一個整數,它的參數里面的$0表示第一個參數,$1表示第二個參數,以此類推。EM_ASM_INT的其他參數會按照順序,傳入 JavaScript 表達式。

                然后,將這個程序編譯成 asm.js。

                
                $ emcc example2.cc -o example2.html
                

                瀏覽器打開網頁example2.html,會顯示val2 == 42

                3.3 EM_ASM 宏系列

                Emscripten 提供以下宏。

                • EM_ASM:調用 JS 代碼,沒有參數,也沒有返回值。
                • EMASMARGS:調用 JS 代碼,可以有任意個參數,但是沒有返回值。
                • EMASMINT:調用 JS 代碼,可以有任意個參數,返回一個整數。
                • EMASMDOUBLE:調用 JS 代碼,可以有任意個參數,返回一個雙精度浮點數。
                • EMASMINT_V:調用 JS 代碼,沒有參數,返回一個整數。
                • EMASMDOUBLE_V:調用 JS 代碼,沒有參數,返回一個雙精度浮點數。

                下面是一個EM_ASM_ARGS的例子。新建文件example3.cc,寫入下面的代碼。

                
                #include <emscripten.h>
                #include <string>
                
                void Alert(const std::string & msg) {
                  EM_ASM_ARGS({
                    var msg = Pointer_stringify($0);
                    alert(msg);
                  }, msg.c_str());
                }
                
                int main() {
                  Alert("Hello from C++!");
                }
                

                上面代碼中,我們將一個字符串傳入 JS 代碼。由于沒有返回值,所以使用EM_ASM_ARGS。另外,我們都知道,在 C / C++ 里面,字符串是一個字符數組,所以要調用Pointer_stringify()方法將字符數組轉成 JS 的字符串。

                接著,將這個程序轉成 asm.js。

                
                $ emcc example3.cc -o example3.html
                

                瀏覽器打開example3.html,會跳出對話框"Hello from C++!"。

                3.4 JavaScript 調用 C / C++ 代碼

                JS 代碼也可以調用 C / C++ 代碼。新建一個文件example4.cc,寫入下面的代碼。

                
                #include <emscripten.h>
                
                extern "C" {
                  double SquareVal(double val) {
                    return val * val;
                  }
                }
                
                int main() {
                  EM_ASM({
                    SquareVal = Module.cwrap('SquareVal', 'number', ['number']);
                    var x = 12.5;
                    alert('Computing: ' + x + ' * ' + x + ' = ' + SquareVal(x));
                  });
                }
                

                上面代碼中,EM_ASM執行 JS 代碼,里面有一個 C 語言函數SquareVal。這個函數必須放在extern "C"代碼塊之中定義,而且 JS 代碼還要用Module.cwrap()方法引入這個函數。

                Module.cwrap()接受三個參數,含義如下。

                • C 函數的名稱,放在引號之中。
                • C 函數返回值的類型。如果沒有返回值,可以把類型寫成null
                • 函數參數類型的數組。

                除了Module.cwrap(),還有一個Module.ccall()方法,可以在 JS 代碼之中調用 C 函數。

                
                var result = Module.ccall('int_sqrt', // C 函數的名稱
                  'number', // 返回值的類型
                  ['number'], // 參數類型的數組
                  [28] // 參數數組
                ); 
                

                回到前面的示例,現在將example4.cc編譯成 asm.js。

                
                $  emcc -s EXPORTED_FUNCTIONS="['_SquareVal', '_main']" example4.cc -o example4.html
                

                注意,編譯命令里面要用-s EXPORTED_FUNCTIONS參數給出輸出的函數名數組,而且函數名前面加下劃線。本例只輸出兩個 C 函數,所以要寫成['_SquareVal', '_main']

                瀏覽器打開example4.html,就會看到彈出的對話框里面顯示下面的內容。

                
                Computing: 12.5 * 12.5 = 156.25 
                

                3.5 C 函數輸出為 JavaScript 模塊

                另一種情況是輸出 C 函數,供網頁里面的 JavaScript 腳本調用。 新建一個文件example5.cc,寫入下面的代碼。

                
                extern "C" {
                  double SquareVal(double val) {
                    return val * val;
                  }
                }
                

                上面代碼中,SquareVal是一個 C 函數,放在extern "C"代碼塊里面,就可以對外輸出。

                然后,編譯這個函數。

                
                $ emcc -s EXPORTED_FUNCTIONS="['_SquareVal']" example5.cc -o example5.js
                

                上面代碼中,-s EXPORTED_FUNCTIONS參數告訴編譯器,代碼里面需要輸出的函數名。函數名前面要加下劃線。

                接著,寫一個網頁,加載剛剛生成的example5.js

                
                <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
                <body>
                <h1>Test File</h1>
                <script type="text/javascript" src="example5.js"></script>
                <script>
                  SquareVal = Module.cwrap('SquareVal', 'number', ['number']);
                  document.write("result == " + SquareVal(10));
                </script>
                </body>
                

                瀏覽器打開這個網頁,就可以看到result == 100了。

                3.6 Node 調用 C 函數

                如果執行環境不是瀏覽器,而是 Node,那么調用 C 函數就更方便了。新建一個文件example6.c,寫入下面的代碼。

                
                #include <stdio.h>
                #include <emscripten.h>
                
                void sayHi() {
                  printf("Hi!\n");
                }
                
                int daysInWeek() {
                  return 7;
                }
                

                然后,將這個腳本編譯成 asm.js。

                
                $ emcc -s EXPORTED_FUNCTIONS="['_sayHi', '_daysInWeek']" example6.c -o example6.js
                

                接著,寫一個 Node 腳本test.js

                
                var em_module = require('./api_example.js');
                
                em_module._sayHi();
                em_module.ccall("sayHi");
                console.log(em_module._daysInWeek());
                

                上面代碼中,Node 腳本調用 C 函數有兩種方法,一種是使用下劃線函數名調用em_module._sayHi(),另一種使用ccall方法調用em_module.ccall("sayHi")

                運行這個腳本,就可以看到命令行的輸出。

                
                $ node test.js
                Hi!
                Hi!
                7
                

                四、用途

                asm.js 不僅能讓瀏覽器運行 3D 游戲,還可以運行各種服務器軟件,比如 LuaRubySQLite。 這意味著很多工具和算法,都可以使用現成的代碼,不用重新寫一遍。

                另外,由于 asm.js 的運行速度較快,所以一些計算密集型的操作(比如計算 Hash)可以使用 C / C++ 實現,再在 JS 中調用它們。

                真實的轉碼實例可以看一下 gzlib 的編譯,參考它的 Makefile 怎么寫。

                五、參考鏈接

                (完)

                留言(43條)

                阮老大好早,半年前作為一個搬運工的我被朋友帶入這一行,就是因為魔獸這個游戲,雖然我不是一個游戲開發,但是看到游戲二字立馬點進來,mark一下再說

                這是打開了js機器學習之路…?

                我以為會順便說一說王者榮耀的【壞笑】

                阮老大,作為一個轉行的新人,心中一直有一個疑問,我是應該繼續按照實現項目的需求去學習從數據庫的處理到頁面的構建,等到很熟練了,再去學一學計算機基礎知識和c,還是現在二者一起學,我不缺時間,這半年多我每天晚上下班都會學到1點之后,必要的話我可以學到半夜三,四點,第二天上班精神還會很好,可是我覺得學的東西太泛,不精,也不基礎,所以現在到底是先從泛到精再補基礎,還是基礎和泛并行,一直到精呢

                JavaScript大法威武JavaScript大法威武JavaScript大法威武

                已經學不過來了,只能靜靜地看著你們繼續前進

                引用蘭宇的發言:

                這半年多我每天晚上下班都會學到1點之后,必要的話我可以學到半夜三,四點,第二天上班精神還會很好,可是我覺得學的東西太泛,不精,也不基礎,所以現在到底是先從泛到精再補基礎,還是基礎和泛并行,一直到精呢

                我現在也是一個新人,覺得基礎這東西,得從實際出發,慢慢領悟,不能太操之過急,你每天學習到1,2點,怎么會有這么多精力呢,相比較,我就慚愧多了。。。

                安裝emscripten的更簡單辦法(自稱)是DockerHub:
                https://hub.docker.com/r/apiaryio/emcc/
                這個直接可以編譯WebAsm了。

                順便推銷我自己用Emscripten包的unrar作例子:
                https://github.com/YuJianrong/node-unrar.js

                引用許杰學node的發言:

                我現在也是一個新人,覺得基礎這東西,得從實際出發,慢慢領悟,不能太操之過急,你每天學習到1,2點,怎么會有這么多精力呢,相比較,我就慚愧多了。。。

                和愛好和習慣有關,我大學時期玩魔獸的時候基本都是晚上2點睡,早上6點半起來繼續奮戰,因為愛好,投入進去了就不會感覺到累。我之前在工地做過放線的,基本都是每天早上6點起床在太陽下干到晚上11,12點,學徒總是被壓榨的,后來做了搬運工,就是扛肥料的,一噸9元,我們一天收入大概在300左右,累了就會喝一瓶冰凍啤酒解乏,所以之前學累了,我會去買一瓶冰凍百威或者雪花和一包花生,邊吃邊學,每個人都會有他的亢奮點,我之前的亢奮點就是一瓶冰凍脾酒,會讓我達到一個最佳狀態,集中精神和不會感到疲乏.另外不管再忙,每坐一到2個小時我都會偷偷的到樓梯間爬一下樓梯,做幾組俯臥撐,晚上下班的時候也會去快走一小時再做幾組深蹲,這可以保持你的肺活量保持你大腦的清醒,午休是必須的,日常午休10分鐘到半小時,如果當天你太累,你必須睡夠一個多小時。不加班的周末最好去做有氧運動,看你個人的喜好,只要是有氧就行。還有一點,我嘗試過白天瘋狂學習,晚上到網吧玩游戲到3點回來,這樣第二天雖然可以上班,但是效率不是一般的低,所以如果想保持一直精神集中學習的話最好戒掉游戲,否則也不要多玩,希望可以幫到你。

                ”運行速度是原生js的50%“,到底是快了還是慢了?

                Rust也可以編譯成webasm

                據稱,asm.js 在瀏覽器里的運行速度,大約是原生代碼的50%左右。 ?

                樓上……
                原生代碼是指native C,不是native javascript……

                真是早,回來看你文章已經是晚上了,不過我覺得web做游戲還是會有些不是很可靠,或者說是我始終覺得怪怪的。希望樓上的人都能夠學有所成。

                3D頁游未來估計也是趨勢,這邊做渲染輸出

                千言萬語匯成一句話,峰哥牛B

                之前在樹莓派上用js操作gpio,因為js速度太慢會錯過數據,感覺用這個有點希望了

                WebGL,three.js 估計也會火起來

                ./emsdk install sdk-incoming-64bit binaryen-master-64bit
                這一步下載速度實在太慢了,有什么其他方法嗎,

                引用蘭宇的發言:

                阮老大好早,半年前作為一個搬運工的我被朋友帶入這一行,就是因為魔獸這個游戲,雖然我不是一個游戲開發,但是看到游戲二字立馬點進來,mark一下再說

                你可以尋找一些名氣不是特別大,但技術能力還是有的小牛或許更加適合現在的你,也會指導你的。

                剛看完 再魯會碼 9點才上班

                在瀏覽器的沙盒模型里跑游戲本身就是個偽命題,看了太多的技術消亡都是因為沒有產生真正的社會生產力,帶不來經濟效應。

                js千秋萬代,一統江湖

                類型系統是 C++的,內存管理是 C++的。這是重新發明了一次 C++ 啊。

                其實現在 WebGL 性能上的瓶頸在于 JS 的運算速度嗎?跟瀏覽器本身是否會有關聯?
                我很想了解的是目前 3D 在瀏覽器端性能瓶頸究竟是什么?

                阮老師終于開始對游戲下手了……期待!

                瀏覽器跑些簡單的H5應該可以,大型游戲太吃內存,操作系統弱了內存小了都帶不上

                引用哥斯拉的發言:

                ./emsdk install sdk-incoming-64bit binaryen-master-64bit
                這一步下載速度實在太慢了,有什么其他方法嗎,

                下載 x2d 里面有,速度那很快!!!

                可惜asm.js沒有被Safari支持,蘋果似乎是一路奔向wasm(iOS11+、Safari11+),或許wasm才是未來的主角,雖然asm.js可讀,可以轉譯成wasm,但應該沒人真去讀這些代碼吧,可讀性好不到哪里去,更多場景是開發者不希望別人看到自己的明文代碼。
                而wasm是優化JIT階段的字節碼,類似于smali,更像二進制的機器碼,更安全的分發,比asm.js更高的壓縮比和執行效率,既生瑜何生亮乎?

                為什么我測的只有IE 10對asm.js兼容,IE其他版本都不兼容。

                搞js的得累死,新東西多如牛毛。es6都還沒掌握。

                阮老師,很高興能認識您,以后還請多多指教。
                我們在用c++來實現一套自己的flash player runtime,保留其強大的API功能,并能以wasm的方式運行在瀏覽器中,現已完成了基礎部分。目的是讓強大的flash API能繼續運行在瀏覽器上使用wasm而不依賴flash player,同時支持JS/ TS以及原有AS3這些腳本語言在上層無縫運行,當然這套API也同時能在c++層使用當作一個跨平臺底層(所有原生端,和wasm),大幅度提高c++前端開發的敏捷性。我們通過半年重構了embind以及編寫了大量腳本層編譯器和工具,渲染用的OpenGL(OpenGL3.0/4.0,提及gles2/es3),根據編譯平臺對應的各filesystem,IO等等(當編譯wasm時,emsdk里實現了很多c++層的API映射,然后通過libXXX.js實現在c++層extern的回調,為了還原flash api,我們自己也做了很多libs)目前已經能將AS3和JS跑在我們這個wasm的runtime了,其功能和開發便利性和之前的flash player一樣。這個是我們的github的 demo。readme里面有幾個demo,原生c++ exe,c++ wasm, as3 js wam. 我們做這個的目的是為了做國人自己的前沿開發平臺,并且今年會在其基礎上開發一套引擎層,對應的工具等等,還請多多指教,我的聯系方式:q: 616267056. https://github.com/JasonHuang3D/AJC-Flash-WebAssembly-Examples/

                ./emsdk install --build=Release sdk-incoming-64bit binaryen-master-64bit

                請教一下,在window下怎么安裝?

                "另外,瀏覽器還會調用 WebGL 通過 GPU 執行 asm.js,即 asm.js 的執行引擎與普通的 JavaScript 腳本不同。這些都是 asm.js 運行較快的原因。"
                ——————————————————————————————————————————
                Seriously? GPU 執行 ams.js ??

                Emscripten愛好者可以關注下《C/C++面向WebAssembly編程》開源圖書:
                https://github.com/3dgen/cppwasm-book

                歡迎提供建議

                引用RedNax的發言:

                安裝emscripten的更簡單辦法(自稱)是DockerHub:
                https://hub.docker.com/r/apiaryio/emcc/
                這個直接可以編譯WebAsm了。

                順便推銷我自己用Emscripten包的unrar作例子:
                https://github.com/YuJianrong/node-unrar.js


                emscripten的Docker image的話 這個可能更好,維護得更密集:
                https://hub.docker.com/r/trzeci/emscripten/

                我從網上下了一個C語言的庫,希望可以編譯成asm.js,但現在只生成wasm,老大指教一下原因?
                下面是編譯命令

                #!/bin/bash
                emcc crypto/*.c -Oz \
                -s DISABLE_EXCEPTION_CATCHING=1 \
                -s BINARYEN_ASYNC_COMPILATION=1 \
                -s ALIASING_FUNCTION_POINTERS=1 \
                -s ALLOW_MEMORY_GROWTH=1 \
                -s WASM=1 \
                -s BINARYEN=1 \
                -s NO_EXIT_RUNTIME=1 \
                -s ASSERTIONS=1 \
                -s STACK_OVERFLOW_CHECK=1 \
                -s EXPORTED_FUNCTIONS="['_cryptonight_hash']" \
                --post-js ../web/lib/worker.js \
                -o ../web/lib/cryptonight.js

                《WebAssembly標準入門》已經上架,歡迎關注
                https://www.epubit.com/book/detail/40619

                -s WASM=1改成0

                不知道這個東西有沒有 java applet快,好多年前的技術了

                https://bellard.org/jslinux/ 這個最新版的就是用的Emscripten 和tinyemu,腦洞爆炸了

                用emscripten轉換的js文件能用在微信小程序上嗎?我試了很久都一直在報錯。

                引用阿飛的發言:

                ”運行速度是原生js的50%“,到底是快了還是慢了?

                不是原生js的50%,是c,c++,rust這些語言的50%。

                我要發表看法

                «-必填

                «-必填,不公開

                «-我信任你,不會填寫廣告鏈接

                99爱视频