Skip to content

Commit

Permalink
overhaul to validator, closer to being in line with current spec
Browse files Browse the repository at this point in the history
  • Loading branch information
Dave Herman committed Mar 10, 2013
1 parent f8ac3bd commit 182e4b9
Show file tree
Hide file tree
Showing 11 changed files with 1,119 additions and 896 deletions.
29 changes: 13 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
# asm.js

![faux logo](https://raw.github.com/dherman/asm.js/master/fauxgo.png)

A Mozilla Research project to specify and develop the extremely optimizable subset of JS targeted by compilers like Emscripten, Mandreel, and LLJS.

## Example

```javascript
function mymodule(global, foreign, buffer) {
function mymodule(stdlib, foreign, heap) {
"use asm";

// -------------------------------------------------------------------------
// SECTION 1: imports
// SECTION 1: globals

var H32 = new global.Int32Array(buffer);
var HU32 = new global.Uint32Array(buffer);
var H32 = new stdlib.Int32Array(heap);
var HU32 = new stdlib.Uint32Array(heap);
var log = foreign.consoleDotLog;

var g_i = 0; // int global
var g_f = 0.0; // double global

// -------------------------------------------------------------------------
// SECTION 2: functions

function f(x, y, z, w) {
function f(x, y) {
// SECTION A: parameter type declarations
x = x|0; // int parameter
y = +y; // double parameter
Expand All @@ -46,24 +47,20 @@ function mymodule(global, foreign, buffer) {
function h(i, x) {
i = i|0;
x = x|0;
H32[(i&0xffffffff)>>4] = x; // masked by 2^k-1, shifted by byte count
ftable_2[(x-2)&2](); // dynamic call of functions in table 2
H32[i>>4] = x; // shifted by byte count
ftable_2[(x-2)&2](); // dynamic call of functions in table 2

// no return necessary when return type is void
}

// -------------------------------------------------------------------------
// SECTION 3: function tables

var ftable_1 = [f];
var ftable_2 = [g, g2]; // all of the same type

// -------------------------------------------------------------------------
// SECTION 4: globals

var g_i = 0; // int global
var g_f = 0.0; // double global

// -------------------------------------------------------------------------
// SECTION 5: exports
// SECTION 4: exports

return { f_export: f, goop: g };
}
Expand Down
36 changes: 10 additions & 26 deletions lib/env.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,22 @@
var dict = require('dict');
var fail = require('./fail');

function Env() {
function Env(v) {
if (!(this instanceof Env))
return new Env();
this._frames = [dict()];
return new Env(v);
this._v = v;
this._dict = dict();
}

Env.prototype.lookup = function lookup(x) {
var a = this._frames, n = a.length, i = n - 1;
while (i >= 0) {
var frame = a[i];
if (frame.has(x))
return frame.get(x);
i--;
}
return null;
return this._dict.get(x) || null;
};

Env.prototype.push = function push() {
this._frames.push(dict());
};

Env.prototype.pop = function pop() {
this._frames.pop();
};

Env.prototype.bind = function bind(x, t) {
Env.prototype.bind = function bind(x, t, loc) {
if (x === 'arguments' || x === 'eval')
fail("illegal binding: '" + x + "'");
var frame = this._frames[this._frames.length - 1];
if (frame.has(x))
fail("duplicate binding: '" + x + "'");
frame.set(x, t);
this._v.fail("illegal binding: '" + x + "'", loc);
if (this._dict.has(x))
this._v.fail("duplicate binding for " + x, loc);
this._dict.set(x, t);
};

module.exports = Env;
22 changes: 21 additions & 1 deletion lib/fail.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
var match = require('pattern-match');

function ValidationError(message, stack) {
Error.call(this, message);
this.stack = stack;
Expand Down Expand Up @@ -32,12 +34,30 @@ function fail(message, src, loc) {
var stack = (new Error).stack
.replace(/[^n]*\n/, "ValidationError: " + message + "\n")
.replace(/\n[^\n]*\n/, "\n");
var e = new ValidationError(message, stack);
var e = new ValidationError(message + locToString(loc), stack);
e.src = src;
e.loc = loc;
throw e;
}

// (Loc) -> str
function locToString(loc) {
return match(loc, function(when) {
when({
start: { line: match.var('sl'), column: match.var('sc') },
end: { line: match.var('el'), column: match.var('ec') }
}, function(vars) {
return " at " + vars.sl + ":" + vars.sc + "-" + vars.el + ":" + vars.ec;
});

when(match.any, function() {
return "";
});
});
}

fail.locToString = locToString;

fail.ValidationError = ValidationError;

module.exports = fail;
57 changes: 0 additions & 57 deletions lib/match.js

This file was deleted.

27 changes: 27 additions & 0 deletions lib/report.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
var ty = require('./types');

function Report(globals, exports) {
this._globals = globals;
this._exports = exports;
}

Report.prototype.getFunction = function(f) {
var global = this._globals.lookup(f);
if (!global || !(global.type instanceof ty.Arrow))
return null;
return global.type;
};

Report.prototype.isSingleExport = function() {
return this._exports.type === 'single';
};

// ( this.isSingleExport => () -> string)
// (!this.isSingleExport => (string) -> string)
Report.prototype.getExport = function(f) {
return this._exports.type === 'single'
? this._exports.export.name
: this._exports.exports.lookup(f).name;
};

module.exports = Report;
Loading

0 comments on commit 182e4b9

Please sign in to comment.