How I tried to compile JavaScript

Post on 20-Jan-2017

66 views 0 download

Transcript of How I tried to compile JavaScript

How I spent my summer

tried to compile javascript

INGVAR STEPANYAN AKA @RREVERSER

Compilers pipeline

Compilers pipeline

function factorial(n) { var result = 1; for (var i = 2; i <= n; i++) { result *= i; } return result;}

‘var result = 1’

[‘v’,‘a‘,‘r’,‘ ‘,‘r’,‘e’,‘s’,‘u’,‘l’,‘t’,‘ ‘,‘=‘,‘ ‘,‘1’]

Keyword Identifier Punctuator Number

[Keyword(‘var’), Identifier(‘result’), Punctuator(‘=‘), Number(‘1’)]

VarDeclaration

VarDeclarator

Identifier Expression

function factorial(n) { var result = 1; for (var i = 2; i <= n; i++) { result *= i; } return result;}

function factorial(n) { var result = 1, i = 2; while (i <= n) { result *= i++; } return result;}

function factorial(n) { var result = 1, i = 1; do { result *= i++; } while (i <= n); return result;}

function factorial(n) { var result = 1; for (var i = 2; i <= n; i++) { result *= i; } return result;}

function factorial(n) { var n, result, i; // all vars result = 1; for (i = 2; i <= n; i++) { result *= i; } return result;}

function factorial(n) { var n, result, i; // all vars result = 1; for (i = 2; i <= n; i = i + 1) { result = result * i; } return result;}

function factorial(n) { var n, result, i; // all vars result = 1; i = 2; while (i <= n) { result = result * i; i = i + 1; } return result;}

function factorial(n) { result = undefined; i = undefined; result = 1; i = 2; while (i <= n) { result = result * i; i = i + 1; } return result;}

// B1result = undefined;i = undefined;result = 1;i = 2;goto B2;

// B4return result;

// B3result = result * i;i = i + 1;goto B2;

// B2cond = i <= n;goto cond ? B3 : B4;

// B1result = undefined;i = undefined;result = 1;i = 2;cond = i <= n;goto cond ? B2 : B3;

// B3return result;

// B2result = result * i;i = i + 1;cond = i <= n;goto cond ? B2 : B3;

// B1r[1] = undefined;i[1] = undefined;r[2] = 1;i[2] = 2;cond[1] = i[2] <= n[1];goto cond ? B2 : B3;

// B3return r;

// B2r = r * i;i = i + 1;cond = i <= n;goto cond ? B2 : B3;

// B1r[1] = undefined;i[1] = undefined;r[2] = 1;i[2] = 2;cond[1] = i[2] <= n[1];goto cond[1] ? B2 : B3;

// B3return r[4];

// B2i[3] = phi(B1:i[2], B2:i[4]);r[3] = phi(B1:r[2], B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= n[1];goto cond[2] ? B2 : B3;

// B1r[2] = 1;i[2] = 2;cond[1] = i[2] <= n[1];goto cond[1] ? B2 : B3;

// B3return phi(B1:r[2], B2:r[4]);

// B2i[3] = phi(B1:i[2], B2:i[4]);r[3] = phi(B1:r[2], B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= n[1];goto cond[2] ? B2 : B3;

// B1cond[1] = 2 <= n[1];goto cond[1] ? B2 : B3;

// B3return phi(B1:1, B2:r[4]);

// B2i[3] = phi(B1:2, B2:i[4]);r[3] = phi(B1:1, B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= n[1];goto cond[2] ? B2 : B3;

// n[1]: 1// B1cond[1] = 2 <= n[1];goto cond[1] ? B2 : B3;

// B3return phi(B1:1, B2:r[4]);

// B2i[3] = phi(B1:2, B2:i[4]);r[3] = phi(B1:1, B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= n[1];goto cond[2] ? B2 : B3;

// n[1]: 1// B1cond[1] = 2 <= 1;goto cond[1] ? B2 : B3;

// B3return phi(B1:1, B2:r[4]);

// B2i[3] = phi(B1:2, B2:i[4]);r[3] = phi(B1:1, B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= 1;goto cond[2] ? B2 : B3;

// n[1]: 1// B1cond[1] = false;goto cond[1] ? B2 : B3;

// B3return phi(B1:1, B2:r[4]);

// B2i[3] = phi(B1:2, B2:i[4]);r[3] = phi(B1:1, B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= 1;goto cond[2] ? B2 : B3;

// n[1]: 1// B1goto B3;

// B3return 1;

// B3return 1;

// n[1]: 10// B1cond[1] = 2 <= 10;goto cond[1] ? B2 : B3;

// B3return phi(B1:1, B2:r[4]);

// B2i[3] = phi(B1:2, B2:i[4]);r[3] = phi(B1:1, B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= 10;goto cond[2] ? B2 : B3;

// n[1]: 10// B1cond[1] = true;goto cond[1] ? B2 : B3;

// B3return phi(B1:1, B2:r[4]);

// B2i[3] = phi(B1:2, B2:i[4]);r[3] = phi(B1:1, B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= 10;goto cond[2] ? B2 : B3;

// n[1]: 10// B1goto B2;

// B3return r[4];

// B2i[3] = phi(B1:2, B2:i[4]);r[3] = phi(B1:1, B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= 10;goto cond[2] ? B2 : B3;

// n[1]: 10// B1goto B2;

// B3return r[4];

// B2i[3] = phi(B1:2, B2:i[4]);r[3] = phi(B1:1, B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= 10;goto cond[2] ? B2 : B3;

// n[1]: 10// B1goto B2;

// B3return r[4];

// B2r[4] = 3628800

// B3return 3628800;

// B1r[1] = undefined;i[1] = undefined;r[2] = 1;i[2] = 2;cond[1] = i[2] <= n[1];goto cond[1] ? B2 : B3;

// B3return r[4];

// B2i[3] = phi(B1:i[2], B2:i[4]);r[3] = phi(B1:r[2], B2:r[4]);r[4] = r[3] * i[3];i[4] = i[3] + 1;cond[2] = i[4] <= n[1];goto cond[2] ? B2 : B3;

function sum(x, y) { return x + y;}

// B1result = x + y;return result;

function sum(x: ???, y: ???) { return x + /* ??? */ y;}

struct JSValue { type: int8; value: int64;}

@readnone function runtime.binop.add(x, y);

function sum(x: JSValue, y: JSValue) { return runtime.binop.add(x, y);}

struct JSValue { type: int8; value: float64;}

@readnone function runtime.binop.add(x, y);

function inc(x: JSValue) { y = JSValue { type: 3 /* number */, value: 1. }; return runtime.binop.add(x, y);}

function distance(x1, y1, x2, y2) { diff1 = runtime.binop.sub(x1, y1); diff2 = runtime.binop.sub(x2, y2);

sqrdiff1 = runtime.binop.mul(diff1, diff1); sqrdiff2 = runtime.binop.mul(diff2, diff2);

sum = runtime.binop.add(sqrdiff1, sqrdiff2); return runtime.unop.sqrt(sum);}

x1_number = runtime.unbox_to_number(x1);y1_number = runtime.unbox_to_number(y1);diff1 = x1_number – y1_number;…sqrdiff1 = diff1 * diff1;…sum = sqrdiff1 + sqrdiff2;result = sqrt(sum);return runtime.box_number(result);

// TODO: More slides