webAssmebly实现js数组排序 使用custom elements和Shadow DOM自定义组件

直接上码了………………

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

输入:

输出:

 结束……

猜你喜欢

转载自www.cnblogs.com/y-y-y-y/p/10301709.html