Giter VIP home page Giter VIP logo

stopify's Introduction

Stopify Build Status

Stopify is a JavaScript-to-JavaScript compiler that makes JavaScript a better target language for high-level languages and web-based programming tools. Stopify enhances JavaScript with debugging abstractions, blocking operations, and support for long-running computations.

Suppose you have a compiler C from language L to JavaScript. You can apply Stopify to the output of C and leave C almost entirely unchanged. Stopify will provide the following features:

  1. Stopify will support long-running L programs without freezing the browser tab. In particular, programs can access the DOM and are not limited to Web Workers.

  2. Stopify can pause or terminate an L program, even if it is an infinite loop.

  3. Stopify can set breakpoints or single-step through the L program, if C generates source maps.

  4. Stopify can simulate an arbitrarily deep stack and proper tail calls. This feature is necessary to run certain functional programs in the browser.

  5. Stopify can simulate blocking operations on the web.

We have tested Stopify with ten languages: (1) C++, (2) Clojure, (3) Dart, (4) Java, (5) JavaScript, (6) OCaml, (7) Pyret, (8) Python, (9) Scheme, and (10) Scala. Some of these are available on the Stopify demo page (www.stopify.org) and the rest are coming soon.

To learn how to use Stopify in your own project, see the Stopify Wiki.

For a technical overview of Stopify, see our PLDI 2018 paper Putting in All the Stops: Execution Control for JavaScript.

stopify's People

Contributors

arjunguha avatar arthertz avatar baxtersa avatar dependabot[bot] avatar jpolitz avatar nicolealese avatar rachitnigam avatar sp1tz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stopify's Issues

Box assignables failing test case

The following fails with cannot read name of undefined inside the shouldBox function.

Grammar = {
  constructAllParses: function() {
    for (;;) {
      const thiz = this;
      ret = ret.concat(
        function(kids) {
          return thiz.applyAction(rule, kids, sppfNode.pos, semActions);
        });
    }
  }
}

20 minute compile times are not reasonable.

For loop desugaring

This test case currently fails in Fission. Verify that Stopify handles it correctly:

var assert = require('assert');

  var skipped = false;
  var i = 0;
  for (; i < 2; i++) {
    if (i == 0) {
      assert(skipped === false); 
      skipped = true;
      continue;
    }
  }
  assert(i === 2);

Update README

We need a better readme. The first paragraph is lifted from our NEPLS talk, which makes no sense to include in the README for software. The rest needs to be updated.

Clojurescript memuse benchmark fails to run when compiled with --new direct

TypeError: Cannot read property 'left' of null                                                                                                                                                                     
    at fun197.funExpr732 [as Lb] (/home/sbaxter/stopify/direct.js:73630:112)                                                                                                                                       
    at fun195.funExpr686 [as Jb] (/home/sbaxter/stopify/direct.js:72180:50)                                                                                                                                        
    at Object.funExpr763 [as box] (/home/sbaxter/stopify/direct.js:74949:73)                                                                                                                                       
    at fun199.funExpr796 [as ia] (/home/sbaxter/stopify/direct.js:77798:56)                                                                                                                                        
    at Object.funExpr37 [as box] (/home/sbaxter/stopify/direct.js:30992:54)                                                                                                                                        
    at Function.funExpr139 [as f] (/home/sbaxter/stopify/direct.js:39945:66)                                                                                                                                       
    at fun212.funExpr917 [as M] (/home/sbaxter/stopify/direct.js:84228:66)                                                                                                                                         
    at Object.funExpr27 [as box] (/home/sbaxter/stopify/direct.js:29332:54)                                                                                                                                        
    at Function.funExpr132 [as a] (/home/sbaxter/stopify/direct.js:39012:65)                                                                                                                                       
    at funExpr1018 (/home/sbaxter/stopify/direct.js:89855:306)                                                                                                                                                     

Re-implement builtin HOFs

Add more here as we encounter them.

String

  • replace

Array

  • every
  • filter
  • find
  • findIndex
  • forEach
  • map
  • reduce
  • reduceRight
  • sort

New desugaring should not have a fixed handleNew function

I came up with a hack to replace the new handler with one that works for callCC:

699a9f9

It is theoretically possible for the callCC transformation to desugar the handleNew function, but it isn't worthwhile.

Here is what I suggest. Let every transformation have a runtime module. Let the runtime module export the new handler. We can assume that the runtime is imported as $__R (or some standard name). Then, desugarNew can invoke $__R.handleNew.

CPS transform: Imported functions are not marked correctly

Functions that are imported, or more generally, functions transformed by the CPS transform need to be marked. The way that CPS does it does not work for the following test case:

const assert = require('assert')

This can fixed by marking all the functions that are transformed in the CPS transform and then checking on that flag before applying.

Stopify as a module

The integration of stopify with the pyret compiler needs stopify to be a require-able module. An programmatic interface like ones used by BuckleScript and Typescript will probably do for now.

We should eventually decide what functions to expose through this library.

Support eval and Function for CPS

Some of the JS benchmarks are using eval. Additionally, Emcscripten also makes use of it.

We should start supporting it. Since implementing eval would require the entire compiler infrastructure to be imported, the implementation should detect eval and only include the compiler if eval is being used.

Function application optimization

Names of first order functions that are marked as 'flat' can be used to remove useless wrapper code around corresponding function applications.

Fix break for functions

Break transformation is still broken. It was not being reported in the desugar tests because loopToFunc transform was disabled for some reason.

Update README.md

The readme is out of date. There is are new ways to compile programs and compile them. Update the readme to reflect the changes.

Add more OCaml benchmarks

Add all of the OCaml benchmarks from the operf-micro library. Currently we have two, of which, only one works.

Stopify should produce runnable files

The transforms should produce individual runnable files as output. The file should export a single function that takes all the arguments as the Stoppable argument currently does.

  • CPS
  • Trampolined CPS
  • Yield
  • Regenerator Yield

Add hello World as test file for each source language

For every language we get working, we should add a simple "hello World" program. The program should be compiled to JS and browserified so it can run as a standalone. Simply add this test to test/should-run/source-language/.

Unify CLI flags to pass options to transforms

Currently we have two ways of passing options to transform: one style used by yield and another one used by the jumper transform.
Instead we can do the following: Pass the whole process.argv object from the stopify binary to the transform and let it handle it.
Or, we could add options for each of the transform through commander (command line parser).

desugarSwitch produces invalid JavaScript or wrong output

It may be the case that a subsequent transformation deals with the output of desugarSwitch. However, when applied in isolation, desugarSwitch produces invalid JavaScript. This will be an issue if we want to use it to do the Pyret-style transformation.

The high-level issue is that desugarSwitch eliminates the switch statement but leaves enclosing break; statements intact. A break; statement jumps out of the innermost enclosing loop or switch statement. So, with the switch eliminated, we either get (1) a syntax error if there is no enclosing loop or (2) wrong result, if we jump out of an enclosing loop.

The solution would be to enclose the output from desugarSwitch in a labelled block and turn the break;s into labelled breaks.

Here is the smallest example. This program, which does not raise an error:

function f() {
  switch(0) {
  case 0:
    break;
  }
}

f();

Is transformed to this program, which raises a SyntaxError:

function f() {
  {
    let _test = 0;
    let _fallthrough = false;

    if (_test === 0 || _fallthrough) {
      _fallthrough = true;

      break;
    }
  }
}

f();

CPS in CPS

RacketScript overflows CPS. Write the CPS transformer in CPS so that this stops happening.

Yo, I heard you like CPS, so I CPS'd your CPS, so that you can CPS in CPS.

yield debug optimization -- Don't yield on every line in runtime library

We should not be stepping inside the runtime library, so it doesn't make sense to add a yield expression on every single line.
Currently, the code adds a yield expression before every statement. Instead of doing this, add a yield expression at the start of the function, and then only add a yield expression if the line has an associated number.

Flatness in presence of assignment

const assert = require('assert');

function myfunc() {
  return 10;
}

myfunc = function() { for (var i = 0; i < 2; i++) { }; return 20; };

assert(myfunc() === 20);
console.log("Should print");
  1. Find a better way to test this bug.
  2. Fix the bug

Wrapping with a top-level function breaks `new Function`

This is was the example I was trying to give the other day. Consider the two programs:

var x = 10;
var f = new Function("return x")
console.log(f())

and

(function () {
  var x = 10;
  var f = new Function("return x")
  console.log(f())
})()

The first one will execute and output 10 while the second one will error out with x is not defined. Since jumper wraps the whole program in a function. We will also see the same failure there.

I'm not sure if it makes sense to focus on this because both webpack and node break the first program. I am leaving this here as documentation.

NOTE: To see the failure, you need to use the browser because even node has the same problem. Run the first program in a tab in the dev tools and run the second program in a new tab.

flatness for new

the direct and wrapper strategies for new can make use of flatness information.

yield transform: new is broken, probably

Prototypal inheritance does not work because of the way we transform newExpressions into .call with a new empty object on the function generator. Any properties that the function is inheriting does not get inherited by the empty object.

Known Hack: If nothing else works, we can duplicate definitions for the functions in order to have a constructor function that returns this.

Pass all tests on travis.

I really want to get everything in a state where all the tests pass on travis. This requires fixing the few tests that fail on CPS.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.