直接上码了………………
.wat源码
(module (type $t0 (func (param i32 i32))) (type $t1 (func (result i32))) (type $t2 (func (param i32 i32 i32 i32))) (type $t3 (func)) (import "env" "returnArr" (func $env.returnArr (type $t0))) (func $getArrayOffset (type $t1) (result i32) i32.const 16) (func $swap (type $t0) (param $p0 i32) (param $p1 i32) (local $l0 i32) get_local $p0 i32.load set_local $l0 get_local $p0 get_local $p1 i32.load i32.store get_local $p1 get_local $l0 i32.store) (func $mainSrot (type $t2) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (local $l0 i32) (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) block $B0 get_local $p2 get_local $p3 i32.ge_s br_if $B0 loop $L1 get_local $p0 get_local $p2 tee_local $l0 i32.const 2 i32.shl i32.add tee_local $l1 i32.load set_local $l4 get_local $p0 get_local $l0 i32.const 1 i32.add tee_local $l6 i32.const 2 i32.shl i32.add tee_local $l2 i32.load set_local $l5 block $B2 block $B3 get_local $l6 get_local $p3 i32.ge_s br_if $B3 get_local $p3 set_local $p2 loop $L4 get_local $p0 get_local $p2 i32.const 2 i32.shl i32.add set_local $l3 block $B5 loop $L6 get_local $l5 get_local $l4 i32.le_s br_if $B5 get_local $l2 get_local $l3 i32.load i32.store get_local $l3 get_local $l5 i32.store get_local $l3 i32.const -4 i32.add set_local $l3 get_local $l1 i32.load set_local $l4 get_local $l2 i32.load set_local $l5 get_local $l6 get_local $p2 i32.const -1 i32.add tee_local $p2 i32.lt_s br_if $L6 br $B2 end end get_local $p0 get_local $l6 i32.const 1 i32.add tee_local $l6 i32.const 2 i32.shl i32.add tee_local $l2 i32.load set_local $l5 get_local $l6 get_local $p2 i32.lt_s br_if $L4 br $B2 end end get_local $p3 set_local $p2 end get_local $l1 get_local $p0 get_local $l6 get_local $l5 get_local $l4 i32.ge_s i32.sub tee_local $l3 i32.const 2 i32.shl i32.add tee_local $l5 i32.load i32.store get_local $l5 get_local $l4 i32.store get_local $p0 get_local $p1 get_local $l0 get_local $l3 call $mainSrot get_local $p2 get_local $p3 i32.lt_s br_if $L1 end end) (func $sort (type $t3) i32.const 16 i32.const 20 i32.const 0 i32.const 19 call $mainSrot i32.const 16 i32.const 20 call $env.returnArr) (table $T0 0 anyfunc) (memory $memory 1) (export "memory" (memory 0)) (export "getArrayOffset" (func $getArrayOffset)) (export "swap" (func $swap)) (export "mainSrot" (func $mainSrot)) (export "sort" (func $sort)))
c源码:
#define N 20 //外部导入javascript函数 extern void returnArr(int * offset, int length); int array[N]; //定义数组并且取到数组首地址 int * getArrayOffset(){ return array; } //交换2个数的值 void swap(int *a , int *b){ int temp; temp = *a; *a = *b; *b = temp; } // 主排序方法 void mainSrot(int array[], int maxlen, int begin, int end){ int i,j; if(begin < end){ i = begin+1; j = end; while (i < j){ if(array[i] > array[begin]){ swap(&array[i],&array[j]); j--; }else{ i++; } } if(array[i] >= array[begin]){ i--; } swap(&array[begin],&array[i]); mainSrot(array,maxlen,begin,i); mainSrot(array,maxlen,j,end); } } //JavaScript调用方法 void sort(){ mainSrot(array,N,0,N-1); //调用JavaScript中的函数 returnArr(array,N); }
html和js源码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> </style> </head> <body> <div class="box"> <label>请输入排序前的数组:</label> <input type="text" class="beforeArr"> <button class="btn">点击排序</button> </div> <script> //继承自HTMLElement class sortArray extends HTMLElement{ constructor(){ super(); let textBore = document.querySelector(".beforeArr"); //事件添加 document.querySelector('.btn').onclick = ()=>{ let beforeArr = this.strArr(textBore.value); //调用webassembly arrSort(beforeArr); } //调用影子dom 添加自定义html模板 let shadow = this.attachShadow({mode:'open'}); let vnode = this.nodeTowfragment('.box'); shadow.appendChild(vnode); } //把dom放入内存中 nodeTowfragment(str){ let el = document.querySelector(str); let fragment = document.createDocumentFragment(); let firstChild; while(firstChild = el.firstChild){ fragment.appendChild(firstChild); } return fragment; } //便利push确保是数字 strArr(el){
let arr = []; for(let i = 0; i < el.length; i++){ arr.push(parseInt(el[i])); } return arr; } } //实例化 customElements.define('sort-array',sortArray); </script> <sort-array></sort-array> <script> function arrSort(arr){ /** 调用浏览器网络下载访问 编译后的wasm文件 */ fetch('program.wasm') //转换为arrayBffer也就是二进制数据 .then(response => response.arrayBuffer()) .then((bytes) => { let memory; //通过浏览器的WebAssembly接口编译初始化wasm模块 WebAssembly.compile(bytes) .then(module => WebAssembly.instantiate(module,{ env:{ /** JavaScript中实现c中调用的函数 能取到排序后的数组 */ returnArr(offset,len){ let arrBuffer = new Uint32Array(memory.buffer,offset,len); //转换为数组 let arr = Array.from(arrBuffer); alert('排序完成:'+arr) ; } } })) .then(instance => { //取出wasm中导出的c函数 let exports = instance.exports; //获得wasm模块中的实例堆内存对象 memory = exports.memory; /** 调用从JavaScript环境向指定的c数组地址填充数据的方法并且传入参数 @param memory //要操作的内存 @param beforeArr //要操作的数组 @param arrOffset //定义c中数组的长度与初始化数组,并且返回该数组的首地址 */ importArrayToBuffer(memory,arr,exports.getArrayOffset()); /** 调用排序方法 @param len //数组的长度 必须与wasm模块导出的getArrayOffset传入的值一样 */ exports.sort(); }) }) } /** 该方法用于从JavaScript环境向指定的c数组地址填充数据 */ function importArrayToBuffer(memory,array,offset){ const importBuffer = new Uint32Array(memory.buffer,offset,array.length); for(let n = 0; n < array.length; n++){ importBuffer[n] = array[n]; } } </script> </body> </html>
输入:
输出:
结束……