Skip to content

Commit

Permalink
Hacks
Browse files Browse the repository at this point in the history
  • Loading branch information
arjunguha committed Mar 4, 2018
1 parent 66ffd47 commit 2b11825
Show file tree
Hide file tree
Showing 12 changed files with 191 additions and 63 deletions.
11 changes: 0 additions & 11 deletions stopify-compiler-cloud-function/test.js

This file was deleted.

111 changes: 105 additions & 6 deletions stopify-compiler-cloud-function/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ genericCompiler('pyjs', `${thirdPartyCompilers}/pyjs`, {
es: 'sane',
hofs: 'builtin',
jsArgs: 'faithful',
requireRuntime: false
requireRuntime: false,
eval: false
});

genericCompiler('emscripten', `${thirdPartyCompilers}/emscripten`, {
Expand All @@ -115,7 +116,8 @@ genericCompiler('emscripten', `${thirdPartyCompilers}/emscripten`, {
es: 'sane',
hofs: 'builtin',
jsArgs: 'simple',
requireRuntime: false
requireRuntime: false,
eval: false
});

genericCompiler('bucklescript', `${thirdPartyCompilers}/bucklescript`, {
Expand All @@ -126,7 +128,8 @@ genericCompiler('bucklescript', `${thirdPartyCompilers}/bucklescript`, {
es: 'sane',
hofs: 'builtin',
jsArgs: 'simple',
requireRuntime: false
requireRuntime: false,
eval: false
});

genericCompiler('scalajs', `${thirdPartyCompilers}/scalajs`, {
Expand All @@ -137,7 +140,8 @@ genericCompiler('scalajs', `${thirdPartyCompilers}/scalajs`, {
es: 'sane',
hofs: 'builtin',
jsArgs: 'simple',
requireRuntime: false
requireRuntime: false,
eval: false
});

genericCompiler('clojurescript', `${thirdPartyCompilers}/clojurescript`, {
Expand All @@ -148,7 +152,8 @@ genericCompiler('clojurescript', `${thirdPartyCompilers}/clojurescript`, {
es: 'sane',
hofs: 'builtin',
jsArgs: 'simple',
requireRuntime: false
requireRuntime: false,
eval: false
});

genericCompiler('dart2js', `${thirdPartyCompilers}/dart2js`, {
Expand All @@ -159,5 +164,99 @@ genericCompiler('dart2js', `${thirdPartyCompilers}/dart2js`, {
es: 'sane',
hofs: 'builtin',
jsArgs: 'simple',
requireRuntime: false
requireRuntime: false,
eval: false
});

stopify.post('/pyjs-fast', bodyParser.text({ type: '*/*' }), async (req, resp) => {
try {
resp.set('Access-Control-Allow-Origin', '*');
resp.set('Access-Control-Allow-Methods', 'POST');

const { filename, exists } = await checkCache('pyjs-fast', req.body);
if (exists) {
return resp.send(filename);
}
console.info(`Compiling PyJS (fast) program (${req.body.length} bytes)`);
const url = `${thirdPartyCompilers}/pyjs-fast`;
const jsCode = await request.post(url, { headers, body: req.body });
console.info(`Stopifying program (${jsCode.length} bytes)`);
const dir = await tmpDir();
try {
const jsPath = `${dir}/original.js`;
await fs.writeFile(jsPath, jsCode + '\npygwtOnLoad();');
const stopifiedJsCode = await stopifyCompiler.stopify(jsPath, {
compileFunction: 'module',
getters: false,
debug: false,
captureMethod: 'lazy',
newMethod: 'wrapper',
es: 'sane',
hofs: 'builtin',
jsArgs: 'faithful',
requireRuntime: false,
eval: false
});
const prelude = await fs.readFile(__dirname + '/../pyjs_prelude.lazy.wrapper.faithful.js');
await bucket.file(filename).save(prelude + stopifiedJsCode + `
$__R.delimit(function () {
$S.onEnd();
});`
);
return resp.send(filename);
}
finally {
await fs.remove(dir);
}
}
catch (exn) {
resp.statusCode = 503;
const reason =
(exn.name === 'StatusCodeError' ? exn.response.body : exn).toString();
console.error(`Error: ${reason}`);
return resp.send(reason.toString());
}
});

stopify.post('/js', bodyParser.text({ type: '*/*' }), async (req, resp) => {
try {
resp.set('Access-Control-Allow-Origin', '*');
resp.set('Access-Control-Allow-Methods', 'POST');

const { filename, exists } = await checkCache('js', req.body);
if (exists) {
return resp.send(filename);
}
console.info(`Compiling JavaScript program (${req.body.length} bytes)`);
const jsCode = req.body;
const dir = await tmpDir();
try {
const jsPath = `${dir}/original.js`;
await fs.writeFile(jsPath, jsCode);
const stopifiedJsCode = await stopifyCompiler.stopify(jsPath, {
compileFunction: false,
getters: false,
debug: true,
captureMethod: 'lazy',
newMethod: 'wrapper',
es: 'sane',
hofs: 'builtin',
jsArgs: 'faithful',
requireRuntime: false,
eval: false
});
await bucket.file(filename).save(stopifiedJsCode);
return resp.send(filename);
}
finally {
await fs.remove(dir);
}
}
catch (exn) {
resp.statusCode = 503;
const reason =
(exn.name === 'StatusCodeError' ? exn.response.body : exn).toString();
console.error(`Error: ${reason}`);
return resp.send(reason.toString());
}
});
2 changes: 1 addition & 1 deletion stopify-compiler-cloud-function/ts/testServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import * as index from './index';

const app = express();
app.use(index.stopifyTesting);
app.listen(8080, '0.0.0.0');
app.listen(8081, '0.0.0.0');

2 changes: 1 addition & 1 deletion stopify-continuations/src/callcc/boxAssignables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ const visitor = {
// topFunction. It shouldn't be boxed since we want to preserve its
// signature.
if (vars.includes(path.node.id.name) &&
!(state.opts.compileFunction && (<any>path.node).topFunction)) {
!(state.opts.compileFunction === true && (<any>path.node).topFunction)) {
const fun = t.functionExpression(
fastFreshId.fresh('fun'),
path.node.params,
Expand Down
2 changes: 1 addition & 1 deletion stopify-continuations/src/callcc/callcc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const visitor: Visitor = {
path.stop();

let toShift;
if (opts.compileFunction) {
if (opts.compileFunction === true) {
if (t.isFunctionDeclaration(path.node.body[0])) {
toShift = (<t.FunctionDeclaration>path.node.body[0]).body.body
}
Expand Down
2 changes: 1 addition & 1 deletion stopify-continuations/src/callcc/delimitTopLevel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const visitor = {
// leave intact
}
else {
if (state.opts.compileFunction && (<any>body[i]).topFunction) {
if (state.opts.compileFunction !== false && (<any>body[i]).topFunction) {
}
else {
body[i] = delimitStmt(body[i]);
Expand Down
3 changes: 2 additions & 1 deletion stopify-continuations/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
export type CaptureMethod = 'eager' | 'retval' | 'lazy' | 'original' | 'fudge';
export type HandleNew = 'direct' | 'wrapper'
export type CompileFunction = boolean | 'module';

export interface CompilerOpts {
compileFunction?: boolean,
compileFunction?: CompileFunction,
getters: boolean,
debug: boolean,
captureMethod: CaptureMethod,
Expand Down
59 changes: 49 additions & 10 deletions stopify-static-website/ts/languages.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as stopifyCompiler from 'stopify';

export interface Language {
compileUrl: string,
defaultCode: string
Expand All @@ -7,6 +9,31 @@ export interface Language {

const compilerBase = 'https://us-central1-arjun-umass.cloudfunctions.net/stopify';

export function runtimeOpts(name: string): stopifyCompiler.Opts {
if (name === 'pyjs' || name === 'js') {
return {
filename: '',
estimator: 'reservoir',
yieldInterval: 100,
timePerElapsed: 1,
resampleInterval: 1,
variance: false,
env: 'chrome',
stop: undefined
};
}

return {
filename: '',
estimator: 'countdown',
yieldInterval: 1,
timePerElapsed: 1,
resampleInterval: 1,
variance: false,
env: 'chrome',
stop: undefined
};
}

export const langs: { [name: string]: Language } = {
'Dart': {
Expand Down Expand Up @@ -86,16 +113,28 @@ object Runner extends JSApp {
stepSupported: false,
aceMode: 'python',
defaultCode:
`def run_forever():
i = 0
while(True):
if i > 10000:
i = 0
i += 1
print i
`def fib(n):
print "fib(" + str(n) + ")"
if n == 0 or n == 1:
return 1
return fib(n-1) + fib(n-2)
run_forever()
`,
compileUrl: `${compilerBase}/pyjs`
print (fib(15))`,
compileUrl: `${compilerBase}/pyjs-fast`
},
JavaScript: {
stepSupported: true,
aceMode: 'js',
defaultCode:
`function fib(n) {
console.log('fib(' + n + ')');
if (n === 0 || n === 1) {
return 1;
}
return fib(n-1) + fib(n-2);
}
fib(15);`,
compileUrl: `${compilerBase}/js`
},
};
18 changes: 5 additions & 13 deletions stopify-static-website/ts/stopify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import AceEditor from 'react-ace';
import { StopifyAce } from './StopifyAce';
import * as browser from 'detect-browser'
import * as ace from 'brace';
import { langs } from './languages';
import { langs, runtimeOpts } from './languages';

import * as stopifyCompiler from 'stopify';

Expand Down Expand Up @@ -40,6 +40,7 @@ class MultilingualStopifyEditor extends React.Component<{}, {language: string}>
<ul className="dropdown-menu">
<li><a href="#" onClick={() => this.setState({ language: 'Dart' })}>Dart</a></li>
<li><a href="#" onClick={() => this.setState({ language: 'Python' })}>Python</a></li>
<li><a href="#" onClick={() => this.setState({ language: 'JavaScript' })}>JavaScript</a></li>
<li><a href="#" onClick={() => this.setState({ language: 'Scala' })}>Scala</a></li>
<li><a href="#" onClick={() => this.setState({ language: 'OCaml' })}>OCaml</a></li>
<li><a href="#" onClick={() => this.setState({ language: 'C++' })}>C++</a></li>
Expand Down Expand Up @@ -141,16 +142,7 @@ class StopifyEditor extends React.Component<{ language: string }, StopifyEditorS
}
}))
.then(path => {
const opts: stopifyCompiler.Opts = {
filename: path,
estimator: 'countdown',
yieldInterval: 1,
timePerElapsed: 1,
resampleInterval: 1,
variance: false,
env: browser.name as any,
stop: undefined
};
const opts = runtimeOpts(this.state.language);
this.setState({
rhs: { type: 'iframe', url: './container.html', opts: opts, path: path }
});
Expand Down Expand Up @@ -249,8 +241,8 @@ class StopifyEditor extends React.Component<{ language: string }, StopifyEditorS
else {
// The "key" in the iframe is unique and forces a full reload.
rhs = <iframe key={this.state.rhs.url} ref={(frame) => this.iframe = frame}
src={this.state.rhs.url} width='100%' height='100%'
style={{border: 'none', overflow: 'hidden'}}>
src={this.state.rhs.url} width='100%'
style={{border: 'none', overflow: 'hidden', height: '80vh' }}>
</iframe>;
}
return <div className="row display-flex">
Expand Down
22 changes: 22 additions & 0 deletions stopify-third-party-compiler-container/server/ts/pyjsFast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import * as request from 'request-promise-native';
import { tmpDir, exec } from './misc';

/**
* Compiles a Python module using PyJS, but does not link it to the PyJS
* runtime system. The produced module is called 'main' and the PyJS runtime
* must be written to load 'main'.
*
* @param code body of the python module
*/
export async function compile(code: string): Promise<string> {
const dir = await tmpDir();
try {
await fs.writeFile(`${dir}/main.py`, code);
return await exec(`pyjscompile main.py`, dir);
}
finally {
await fs.remove(dir);
}
}
2 changes: 2 additions & 0 deletions stopify-third-party-compiler-container/server/ts/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as bucklescript from './bucklescript';
import * as clojurescript from './clojurescript';
import * as scalajs from './scalajs';
import * as dart2js from './dart2js';
import * as pyjsFast from './pyjsFast';

export const app = express();
app.use(morgan('short'));
Expand All @@ -31,5 +32,6 @@ compiler('/bucklescript', bucklescript.compile);
compiler('/clojurescript', clojurescript.compile);
compiler('/scalajs', scalajs.compile);
compiler('/dart2js', dart2js.compile);
compiler('/pyjs-fast', pyjsFast.compile);

app.listen(8080);

0 comments on commit 2b11825

Please sign in to comment.