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

Compile to JavaScript #838

Closed
MichaelJCole opened this issue Sep 12, 2019 · 8 comments
Closed

Compile to JavaScript #838

MichaelJCole opened this issue Sep 12, 2019 · 8 comments

Comments

@MichaelJCole
Copy link

MichaelJCole commented Sep 12, 2019

Using the starter project, at webassembly.studio, I can compile an AssemblyScript.ts file to wasm.

Question: How can I compile AssemblyScript.ts to JavaScript?

This is what I have so far:

gulp.task("build-wasm", callback => {
  const asc = require("assemblyscript/bin/asc");
  asc.main([
    "nBodyForces.ts",
    "--baseDir", "assembly",
    "--binaryFile", "../out/nBodyForces.wasm",
    "--sourceMap",
    "--measure",
    "--runtime", "half",
    "--optimize"
  ], callback);
});

gulp.task('build-js', function () {
  const tsProject = ts.createProject('assembly/tsconfig.json', {
    outFile: 'nBodyForces.js'
  });

  return tsProject.src()
      .pipe(tsProject())
      .pipe(gulp.dest('out'));
});


gulp.task("default", ["build-wasm", "build-js"]);
@MaxGraey
Copy link
Member

Hi @MichaelJCole!
I saw you experiment btw. nice. I wont give some minor advices how you could improve performance more before comparison with JS:

  • switch "--optimize" to -O3
  • add --noAssert
  • use unchecked wrapped for array's index access. like:
    intead
let d = data[i * 3];
ret[i * 2] = ret[i * 2] + f[0];    // body[i]

use

let d = unchecked(data[i * 3]);
unchecked(ret[i * 2] = ret[i * 2] + f[0]);    // body[i]

This skip runtime range check and potentially could improve speed

About compilation to JavaScript. AssemblyScript don't provide this, but AS code mostly compatible with typescript so you could use original tsc compiler for that. Just follow portability instructions in docs

@dcodeIO
Copy link
Member

dcodeIO commented Sep 12, 2019

The compiler also has an option to emit a JS file by adding "--asmjsFile", "../out/nBodyForces.js",. This essentially compiles to Wasm first, and then utilizes Binaryen's wasm2js to convert it to JS. The resulting JS file (an ES module) resembles asm.js, and there's a pending issue with export names becoming mangled currently.

@MichaelJCole
Copy link
Author

@dcodeIO nailed it, thank you!

@MaxGraey thanks! After the Canvas version is a WebVR version with A-Frame. Time to sex-up my portfolio :-)

@MichaelJCole
Copy link
Author

Hey, this is what I came up with. I'll make a PR for the starter project if you're into that :-)

This gulpfile creates these files:

/out/nBodyForces.asc.js  -  binaryen's JS output (scary basement! but not bad)
/out/nBodyForces.tsc.js   -  typescript's output (friendly)
/out/nBodyForces.wasm  - binaryen's wasm 
/out/nBodyForces.wasm.map 

/assembly/tsconfig.json

{
  "// See https://docs.assemblyscript.org/details/portability": true,
  "// extends": "../node_modules/assemblyscript/std/assembly.json",
  "extends": "../node_modules/assemblyscript/std/portable.json",
  "include": [
    "./**/*.ts",
    "constants.js"
  ]
}

gulpfile

const gulp = require("gulp");
const ts = require('gulp-typescript');
const rename = require('gulp-rename');
const portable = require("assemblyscript/std/portable");

gulp.task("build-wasm", callback => {
  const asc = require("assemblyscript/bin/asc");
  asc.main([
    "nBodyForces.ts",
    "--baseDir", "assembly",
    "--binaryFile", "../out/nBodyForces.wasm",
    "--asmjsFile", "../out/nBodyForces.asc.js",
    "--runtime", "half",
    "-O3",        // https://github.com/AssemblyScript/assemblyscript/issues/838
    "--noAssert",
    "--sourceMap",
    "--measure",
  ], callback);
});

gulp.task('build-js', function () {
  const tsProject = ts.createProject('assembly/tsconfig.json');

  return tsProject.src()
      .pipe(tsProject())
      .pipe(rename(function (path) {
        path.basename += ".tsc";
      }))
      .pipe(gulp.dest('out'));
});

gulp.task("build", ["build-wasm", "build-js"]);
gulp.task("default", ["build"]);

@MaxGraey
Copy link
Member

@MichaelJCole
"An implementation of the classical physics "3-body problem" using browser Canvas, WebAssembly and C."
Probably you mean
"....WebAssembly and AssemblyScript" ? 😄

@MichaelJCole
Copy link
Author

@MaxGraey hey, I'm wrapping up my current adventure in AssemblyScript

These two visualizations - 2d w/ canvas and 3d w/ a-frame use the same simulator running in a Web Worker with AssemblyScript to wasm. They even slightly work on mobile.

https://michaeljcole.github.io/n-body-wasm-canvas/
https://michaeljcole.github.io/n-body-wasm-webvr/

The gulpfile has both rollup for the AssemblyScript loader and asc for the typescript compiler.

Mmmmm. Build scripts. Fun times!

@guest271314
Copy link

@MichaelJCole Does that AssemblyScript to JavaScript code still work?

@guest271314
Copy link

@dcodeIO @MaxGraey What is the canonical process to compile to JavaScript circa 2025?

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

No branches or pull requests

4 participants