Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Making for Web with WebAssembly

Making for Web with WebAssembly

WebAssembly or WASM is a low-level bytecode format for in-browser client-side scripting, evolved from JavaScript. Its initial aim is to support compilation from C and C++, though other source languages such as Rust are also supported.

Raphael Amorim

December 15, 2017
Tweet

More Decks by Raphael Amorim

Other Decks in Technology

Transcript

  1. Making
    for
    the
    Web
    with
    WebAssembly
    @ R A P H A M U N D I
    アモリム

    View Slide

  2. RAPHAEL
    AMORIM
    Student •
    React-tv •
    globo.com •
    js foundation •
    jQuery member •
    Mozillian •
    Metido a besta •
    some git push.

    Working most part of his
    open source projects.
    @ R A P H A M U N D I
    アモリム

    View Slide

  3. View Slide

  4. View Slide

  5. @ R A P H A M U N D I
    定義
    why
    wasm
    now?

    View Slide

  6. @ R A P H A M U N D I
    JavaScript was created in 1995

    View Slide

  7. @ R A P H A M U N D I
    It wasn’t designed to be fast,
    and for the first decade, it wasn’t fast.
    Then the browsers started
    getting more competitive.

    View Slide

  8. @ R A P H A M U N D I
    In 2008, a period that people
    call the performance wars began.
    Multiple browsers added just-in-time compilers*.
    * As JavaScript was running, the JIT could see patterns
    and make the code run faster based on those patterns.

    View Slide

  9. @ R A P H A M U N D I
    The introduction of these JITs led to an
    inflection point in the performance of JavaScript.
    Execution of JS was 10x faster.

    View Slide

  10. @ R A P H A M U N D I
    With this improved performance.
    JavaScript started being used for
    things no one ever expected it to be used for,
    like server-side programming with Node.js.

    View Slide

  11. @ R A P H A M U N D I
    The performance improvement made it
    feasible to use JavaScript on
    a whole new class of problems.

    View Slide

  12. @ R A P H A M U N D I
    Compile to the web
    JS is standards-based, runs everywhere
    Avoid high cost of porting code
    Reuse existing native libraries

    View Slide

  13. @ R A P H A M U N D I
    faster decoding than JavaScript (up to 20×)

    thread & SIMD support *

    View Slide

  14. @ R A P H A M U N D I
    定義
    WebAssembly (WASM)

    View Slide

  15. @ R A P H A M U N D I
    WebAssembly or WASM
    is a low-level bytecode format
    for in-browser client-side scripting,
    evolved from JavaScript.

    View Slide

  16. @ R A P H A M U N D I
    Initial aim is to support compilation from C and C++,
    though other source languages

    such as Rust are also supported.

    View Slide

  17. @ R A P H A M U N D I
    Initial implementation of WebAssembly support in
    browsers will be based on the featureset of asm.js

    View Slide

  18. @ R A P H A M U N D I
    定義
    ASMJS

    View Slide

  19. @ R A P H A M U N D I
    Intermediate programming language designed to allow
    computer software written in languages such as C to be
    run as web applications.

    View Slide

  20. @ R A P H A M U N D I
    Consists of a strict subset of JavaScript,

    into which code written in statically-typed

    languages with manual memory management

    is translated by a source-to-source compiler

    such as Emscripten (based on LLVM)

    View Slide

  21. @ R A P H A M U N D I
    size_t strlen(char *ptr) {

    char *curr = ptr;

    while (*curr != 0) {

    curr++;

    }

    return (curr - ptr);

    }

    View Slide

  22. @ R A P H A M U N D I
    function strlen(ptr) {

    ptr = ptr|0;

    var curr = 0;

    curr = ptr;

    while (MEM8[curr]|0 != 0) {

    curr = (curr + 1)|0;

    }

    return (curr - ptr)|0;

    }

    View Slide

  23. @ R A P H A M U N D I
    Note:


    Much of performance gain over

    normal JavaScript is due to 100% type consistency

    and virtually no garbage collection.

    View Slide

  24. @ R A P H A M U N D I
    定義
    WebAssembly
    binary format

    View Slide

  25. @ R A P H A M U N D I
    int factorial(int n) {
    if (n == 0)
    return 1;
    else
    return n * factorial(n-1);
    }

    View Slide

  26. @ R A P H A M U N D I
    get_local 0
    i64.eqz
    if i64
    i64.const 1
    else
    get_local 0
    get_local 0
    i64.const 1
    i64.sub
    call 0
    i64.mul
    end
    Linear Assembly Bytecode

    View Slide

  27. @ R A P H A M U N D I
    20 00
    50
    04 7E
    42 01
    05
    20 00
    20 00
    42 01
    7D
    10 00
    7E
    0B
    WASM binary encoding

    View Slide

  28. @ R A P H A M U N D I
    The WASM compiler system internally
    uses s-expressions for parsing simplicity
    as well to handle intermediate code.

    View Slide

  29. @ R A P H A M U N D I
    (module
    (type $FUNCSIG$dd (func (param f64) (result f64)))
    (import "global.Math" "exp" (func $exp (param f64) (result f64)))
    (memory 256 256)
    (export "memory" (memory 0))
    (func $doubleExp (param $0 f64) (result f64)
    (f64.mul
    (call $exp
    (get_local $0)
    )
    (f64.const 2)
    )
    )
    (export "doubleExp" (func $doubleExp))
    )

    View Slide

  30. @ R A P H A M U N D I
    定義
    RUST.

    View Slide

  31. @ R A P H A M U N D I
    programming language sponsored by
    Mozilla Research

    View Slide

  32. @ R A P H A M U N D I
    Safe, concurrent, practical language.

    View Slide

  33. @ R A P H A M U N D I
    Supporting functional and imperative-procedural
    paradigms.

    View Slide

  34. @ R A P H A M U N D I
    Rust is syntactically similar to C++, but its designers
    intend it to provide better memory safety while
    maintaining performance.

    View Slide

  35. @ R A P H A M U N D I
    guaranteed memory safety
    threads without data races
    trait-based generics
    pattern matching <3
    type inference
    minimal runtime
    efficient C bindings
    zero-cost abstractions
    move semantics

    View Slide

  36. @ R A P H A M U N D I
    fn main() {
    let greetings = [“Ola", "Hello", "Hola", “Bonjour”];
    for (num, greeting) in greetings.iter().enumerate() {
    print!("{} : ", greeting);
    match num {
    0 => println!(“Esse código é modificável e executável!"),
    1 => println!("This code is editable and runnable!"),
    2 => println!("¡Este código es editable y ejecutable!"),
    3 => println!("Ce code est modifiable et exécutable !"),
    _ => {},
    }
    }
    }

    View Slide

  37. @ R A P H A M U N D I
    定義
    CREATE
    WITH
    RUST/
    WASM

    View Slide

  38. View Slide

  39. @ R A P H A M U N D I
    $ curl https://sh.rustup.rs -sSf | sh

    View Slide

  40. @ R A P H A M U N D I
    $ source $HOME/.cargo/env

    View Slide

  41. @ R A P H A M U N D I
    $ rustup target add wasm32-unknown-
    emscripten

    View Slide

  42. @ R A P H A M U N D I
    $ curl https://s3.amazonaws.com/mozilla-
    games/emscripten/releases/emsdk-
    portable.tar.gz | tar -xv -C ~/

    View Slide

  43. @ R A P H A M U N D I
    $ brew install cmake

    View Slide

  44. @ R A P H A M U N D I
    $ cd ~/emsdk-portable
    ./emsdk update
    ./emsdk install sdk-incoming-64bit
    ./emsdk activate sdk-incoming-64bit

    View Slide

  45. View Slide

  46. @ R A P H A M U N D I
    $ emcc -v
    *1.37.9

    View Slide

  47. @ R A P H A M U N D I
    $ cargo init wasm-demo --bin
    *1.37.9

    View Slide

  48. @ R A P H A M U N D I
    $ rustup override set nightly

    View Slide

  49. @ R A P H A M U N D I
    #[derive(Debug)]
    enum Direction { North, South, East, West }
    fn is_north(dir: Direction) -> bool {
    match dir {
    Direction::North => true,
    _ => false,
    }
    }
    fn main() {
    let points = Direction::South;
    println!("{:?}", points);
    let compass = is_north(points);
    println!("{}", compass);
    }
    src/main.rs

    View Slide

  50. @ R A P H A M U N D I
    $ cargo run
    Compiling wasm-rust v0.1.0 (file:///Users/raphael.amorim/Documents/
    gcom/webassembly-and-rust/examples/wasm-rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.66 secs
    Running `target/debug/wasm-rust`
    South
    false
    src/main.rs

    View Slide

  51. @ R A P H A M U N D I
    $ cargo build
    --target=wasm32-unknown-emscripten
    --release
    src/main.rs

    View Slide

  52. @ R A P H A M U N D I
    $ tree target
    target
    └── wasm32-unknown-emscripten
    └── release
    ├── build
    ├── deps
    │ ├── wasm_demo-9c23ae9a241f12fa.asm.js
    │ ├── wasm_demo-9c23ae9a241f12fa.js
    │ └── wasm_demo-9c23ae9a241f12fa.wasm
    ├── examples
    ├── incremental
    ├── native
    ├── wasm-demo.d
    └── wasm-demo.js
    (brew install tree for OSX)

    View Slide

  53. @ R A P H A M U N D I


    <br/>// This is read and used by `site.js`<br/>var Module = {<br/>wasmBinaryFile: "site.wasm"<br/>}<br/>




    (brew install tree for OSX)

    View Slide

  54. @ R A P H A M U N D I
    SHELL := /bin/bash
    all:
    cargo build --target=wasm32-unknown-emscripten --release
    mkdir -p site
    find target/wasm32-unknown-emscripten/release/deps -type f -name "*.wasm" | xargs -
    I {} cp {} site/site.wasm
    find target/wasm32-unknown-emscripten/release/deps -type f ! -name "*.asm.js" -name
    "*.js" | xargs -I {} cp {} site/site.js
    Automatize it.

    View Slide

  55. @ R A P H A M U N D I
    $ tree site
    site
    ├── index.html
    ├── site.js
    └── site.wasm

    View Slide

  56. @ R A P H A M U N D I
    cd site && python -m SimpleHTTPServer

    View Slide

  57. View Slide

  58. @ R A P H A M U N D I use std::os::raw::c_char;
    use std::ffi::CString;
    use std::collections::HashMap;
    #[no_mangle]
    pub fn get_data() -> *mut c_char {
    let mut data = HashMap::new();
    data.insert("Alice", "send");
    data.insert("Bob", "recieve");
    data.insert("Carol", "intercept");
    let descriptions = data.iter()
    .map(|(p,a)| format!("{} likes to {} messages", p, a))
    .collect::>();
    CString::new(descriptions.join(", "))
    .unwrap()
    .into_raw()
    }
    fn main() {
    // Deliberately blank.
    }
    src/main.rs

    View Slide

  59. @ R A P H A M U N D I
    var Module = {
    wasmBinaryFile: "site.wasm",
    onRuntimeInitialized: main,
    };
    function main() {
    var getData = Module.cwrap('get_data', 'string', []);
    console.log(getData());
    };
    src/main.rs

    View Slide

  60. View Slide

  61. refs|参考⽂文献
    github.com/
    raphamorim/
    wasm-and-rust

    View Slide

  62. refs|参考⽂文献
    • https://en.wikipedia.org/wiki/WebAssembly

    • https://en.wikipedia.org/wiki/Rust_(programming_language)

    • https://hoverbear.org/2017/04/06/the-path-to-rust-on-the-web/

    • http://cultureofdevelopment.com/blog/build-your-first-thing-with-web-assembly/

    • https://github.com/mbasso/awesome-wasm

    • https://hacks.mozilla.org/2017/02/a-cartoon-intro-to-webassembly/

    • https://github.com/mrfr0g/rust-webassembly

    • https://internals.rust-lang.org/t/state-of-webassembly-and-rust/6077

    • https://www.rust-lang.org/en-US/

    • https://hacks.mozilla.org/2017/02/a-crash-course-in-assembly/

    • https://www.hellorust.com/emscripten/slides/rbr-talk/

    • https://hoverbear.org/2017/03/03/setting-up-a-rust-devenv

    View Slide

  63. T H A N K S !
    @ R A P H A M U N D I
    アモリム

    View Slide