Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why not transpile to rust #1429

Closed
solidsnail opened this issue Aug 6, 2020 · 5 comments
Closed

Why not transpile to rust #1429

solidsnail opened this issue Aug 6, 2020 · 5 comments
Labels

Comments

@solidsnail
Copy link

Hi there,

I was wondering why you didn't go with the route of making a typesript to rust transpiler and then generate js code with the help of wasm-pack

From:

export greet(){
 let x: boolean = true;
 if(x){
  console.log("Greetings, x is true");
 }
}

(AST Traversing in between)

To:

#[wasm_bindgen]
pub fn greet() {
    let x: bool = true; 
    if x {
        println!("Greetings, x is true");
    }
}

Are there any reasons ?

@solidsnail solidsnail changed the title Why not transpile from rust Why not transpile to rust Aug 6, 2020
@gabriel-fallen
Copy link

@solidsnail what about Automatic Memory Management (which AssemblyScript provides and Rust doesn't)? For the start. 😉

@gabriel-fallen
Copy link

@solidsnail immediately to the second question. AssemblyScript provides four options for a Runtime Support Library of different sizes and functionality (https://www.assemblyscript.org/runtime.html). What's your idea of reimplementing it with Rust (using no-std I presume)?

@dcodeIO
Copy link
Member

dcodeIO commented Aug 6, 2020

In the case of AssemblyScript, a language quite different to Rust, transpiling to Rust would effectively just replace the low-level layer of Binaryen IR with a different low-level layer of Rust that wasn't specifically designed for the task. Can be done to some extend, with the slight benefit of effectively being able to pipe through LLVM (I expect this benefit to diminish over time), but that'd also mean two layers of standard libraries with two layers of compilers, very likely yielding suboptimal and unnecessarily clumsy final WebAssembly code. The drawbacks quickly outweigh the benefits if there are any, i.e. making the whole thing larger to download, harder to set up, making compilation much slower, and ultimately being unable to bootstrap the compiler.

@MaxGraey
Copy link
Member

MaxGraey commented Aug 6, 2020

Also great reason described by Alon why we use Binaryen instead of LLVM or LLVM based languages

@solidsnail
Copy link
Author

I see, thanks for the insights.

I'm actually more keen on seeing things from a DX perspective, thinking off something along the lines of this:

counter.tsx:

import { WASM, Component, i32 } from "./lib";

@Component
export class Counter {
  wasm_state = {
    count: 1,
  };

  @WASM({
    getter: true,
  })
  getCount() {
    return this.wasm_state.count;
  }

  @WASM({
    setter: true,
  })
  setCount(count: i32) {
    this.wasm_state.count = count;
  }

  render() {
    return (
      <div>
        <h1>Count: {this.getCount()}</h1>
      </div>
    );
  }
}

AST typescript traverse , transform and generate files:

counter.wasm:

extern crate cfg_if;
extern crate wasm_bindgen;

mod utils;

use cfg_if::cfg_if;
use wasm_bindgen::prelude::*;

cfg_if! {
    if #[cfg(feature = "wee_alloc")] {
        extern crate wee_alloc;
        #[global_allocator]
        static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
    }
}


#[wasm_bindgen]
pub struct State {
    count: i32,
}

#[wasm_bindgen]
impl State {
    #[wasm_bindgen(constructor)]
    pub fn new(count: i32) -> State {
        State { count }
    }

    #[wasm_bindgen(getter)]
    pub fn getCount(&self) -> i32 {
        self.count
    }

    #[wasm_bindgen(setter)]
    pub fn setCount(&mut self, count: i32) {
        self.count = count;
    }
}

counter.js:

import {html, render} from 'lit-html';
import { State  } from './counter.wasm';


export class Counter extends HTMLElement{
    constructor(){
        super();
        State.setCount(1)
        this.renderHtml()
    }
    
    renderHtml(){
      render(html`
        <div>
            <h1>Count: ${State.getCount()}</h1>
        </div>
        `, this);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants