WebAssembly를 사용해 보았습니다.

이게 뭐야



이름 그대로 브라우저로부터 어셈블리를 실행할 수 있도록 하는 기술이며, 고속화 수단, 혹은 JavaScript의 처리계로 할 수 없는 일을 하는 등의 목적으로 제안되었다.

현재 많은 브라우저에서 지원되는 asm.js와의 차이점은 JavaScript의 하위 집합이기 때문에 로드 타임에 문제가 있었던 asm.js에 대해 WebAssembly에서 직접 바이너리를로드하여이 문제를 해결합니다. 있습니다.

현재 Chrome(Canary)에 구현되어 쉽게 시도할 수 있게 되었다.

시도했다.



참고한 기사


  • WebAssembly 사용 (C / C ++을 WebAssembly로 변환하여 Chrome에서 실행)
  • WebAssembly를 사용하여 브라우저에서 자작 언어를 실행해 봅시다.

  • 사용하는 것


  • Google Chrome Canary
  • llvm
  • clang
  • binaryen
  • sexpr-wasm-prototype

  • Google Chrome Canary



    WebAssembly를 사용하려면 chrome://flags/#enable-webassembly를 체크하고 활성화하십시오.

    llvm


    -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly 를 붙여 cmake 한다.

    brew를 통해 설치하는 경우에는 brew edit llvm 로 추가.

    clang



    Mac에 표준으로 들어가 있는 clang에서는 잘 되지 않았기 때문에 clang-3.8 를 사용했다. 아마 brew install llvm38 --with-clang 의 것이라고 생각한다.

    binaryen



    htps : // 기주 b. 코 m / 우 삐세 mbly / 비나 ぇ

    복제되어 빌드 및 설치

    sexpr-wasm-prototype



    htps : // 기주 b. 코 m / 우 삐세 mbly / 세 xpr - smp 여과 type

    복제되어 빌드 및 설치

    (클론한 뒤 git submodule update --init 잊지 말고)

    변환해보기



    변환은 이런 느낌의 흐름
    C/C++ -> LLVM bitecode -> Assembly -> S-expression -> binary
    

    이번에는 C++의 코드를 변환한다.

    sample.cpp
    extern "C" {
      int fib(int n) {
        int i, t, a = 0, b = 1;
        for (i = 0; i < n; i++) {
          t = a + b; a = b; b = t;
        }
        return b;
      }
    }
    

    C++의 경우, 함수명이 mangling되어 버리므로, 회피하기 위해(때문에) extern "C" {} (을)를 하고 있다.

    1. 우선 C++에서 LLVM 바이트코드로 변환
    clang++-3.8 sample.cpp -emit-llvm --target=wasm32 -Oz -c -o sample.bc
    

    2. LLVM 바이트 코드에서 어셈블리로 변환
    llc sample.bc -march=wasm32 -filetype=asm -o sample.s
    

    3. 어셈블리에서 S 표현식으로 변환
    s2wasm sample.s > sample.wast
    

    4. S 표현식에서 WebAssembly 바이너리로 변환
    sexpr-wasm sample.wast -o sample.wasm
    

    이것으로 읽어들이기 위한 .wasm 가 완성된다.

    전술한 참고로 한 기사에서는 LLVM IR 형식( .ll )으로 변환하고 나서 어셈블리로 변환하고 있었다. 이 방법에서도 유사한 결과가 얻어진다.

    실행해보기



    js는 이런 느낌

    index.js
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'sample.wasm', true);
    xhr.responseType = 'arraybuffer';
    xhr.onload = function() {
      var binary = xhr.response;
      var binarray = new Uint8Array(binary);
      var module = Wasm.instantiateModule(binarray);
      console.log(module.exports);
      var fib = module.exports.fib;
      var arr = [];
      for (var i = 0; i < 20; i++) {
        arr.push(fib(i));
      }
      console.log(arr);
    };
    xhr.send(null);
    

    완성 된 바이너리를 XHR로 가져와 Uint8Array로 변환하고 Wasm.instantiateModule에 던지면 객체가 반환됩니다.



    돌려 온 객체의 exports 안에 C++로 정의한 함수가 들어 있으므로 그대로 인수를 건네주어 액세스 할 수 있다.

    이번에는 20개의 피보나치 수열을 표시할 뿐.

    에서



    원인을 모르겠지만 clang에서 빌드로 최적화를 끊으면 WebAssembly 바이너리는 가능하지만 실행하면 오류가 발생했습니다. 언젠가 해결하고 싶습니다.



    Web의 프런트 엔드에 C/C++의 코드가 개입해 온다고 생각하면 프레임워크나 라이브러리의 패러다임도 바뀌어 오는 것일지도 모른다.

    지금 뜨거워지고 있는 WebAssembly이지만, 아직 정보는 적기 때문에, 다시 시도할 기회가 있으면 해 보려고 한다.

    이번 코드는 github에 포이 해 두었다.

    htps : // 기주 b. 코 m / p ly 뭉치 b ぇ s 쓰레기 담배 / 와 s m 사 mp ぇ

    좋은 웹페이지 즐겨찾기