Skip to content

GDenisC/jsc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JavaScript Compiler

Checklist

  • JavaScript reader - babel

  • Class Destructuring (WIP)

  • Precalculation

  • Unglobalization

  • @inline

  • @macro

  • @const

  • Stack

  • Registers

  • Bytecode

  • ASM.js

  • WASM

Converts a Class declaration into a series of equivalent function declarations. Only works with top-level classes.

  • V8 optimizations
  • Better code compression results

Example 1

class Foo {
    constructor() {
        this.x = 1;
    }

    get x() {
        return this.x;
    }
}

console.log(new Foo().x);
function Foo_constructor() {
    /* or just return { x: 1 } */
    var self = {};
    self.x = 1;
    return self;
}

function Foo_get_x(self) {
    return self.x;
}

console.log(Foo_get_x(Foo_constructor()));

Example 2

class Foo {
    getHelloString() {
        return 'hello';
    }
}

class Bar extends Foo {
    getHelloString() {
        return super.getHelloString() + ' world';
    }
}

console.log(new Bar().getHelloString());
function Foo_getHelloString(self) {
    return 'hello';
}
function Bar_getHelloString(self) {
    return Foo_getHelloString(self) + ' world';
}

console.log(Bar_getHelloString({}));

Precalculation

function foo(x) {
    return Math.sqrt(x * x + x * x) + 60 * 2 - 20;
}
function foo(x) {
    var _0 = x * x;
    return Math.sqrt(_0 + _0) + 100;
}

Unglobalization

  • Patches some hooking techniques (replacing a function/method with a malicious version)
  • Better code compression results
function randomInt(x) {
    return Math.floor(Math.random() * x);
}
var Math_floor = Math.floor,
    Math_random = Math.random;
function randomInt(x) {
    return Math_floor(Math_random() * x);
}

@inline

functions and class methods

/** @inline */
function randomInt(x) {
    return Math.floor(Math.random() * x);
}

randomInt(10);
randomInt(20);
Math.floor(Math.random() * 10);
Math.floor(Math.random() * 20);

@macro

//@macro if DEBUG
function log(message) {
    console.log(message);
}
//@macro else
function log(_) {}
//@macro endif

log('Hello!');
//@macro set DEBUG 1
function log(message) {
    console.log(message);
}

log('Hello!');
//@macro set DEBUG 0
function log(_) {}

log('Hello!');

@const

Variable that will be evaluated at compile time

/** @const */
const ARR = [1, 10, 100, 1000];

/** @const */
const WORD = (() => {
    let words = ['answer is ', 'answer = ', 'hello, '];
    return words[Math.floor(Math.random() * words.length)];
})();

console.log(WORD + ARR[2] * ARR[3]);

if i run the program 3 times:

console.log('answer is ' + 100 * 1000);
console.log('answer = ' + 100 * 1000);
console.log('hello, ' + 100 * 1000);

Stack

function random(min, max) {
    return min + Math.random() * (max - min);
}

console.log(random(10, 20));
var __stack = [];
function random() {
    __stack.push(__stack[__stack.length - 1] + Math.random() * (__stack[__stack.length - 2] - __stack.pop()));
    __stack.pop();
}
__stack.push(10 /* min */, 20 /* max */);
random();
console.log(__stack.pop());

Registers

Recursion is not supported

function random(min, max) {
    return min + Math.random() * (max - min);
}

console.log(random(10, 20));
var reg0, reg1;
function random() {
    reg0 = reg0 + Math.random() * (reg1 - reg0);
}
reg0 = 10 /* min */;
reg1 = 20 /* max */;
random();
// reg1 is "released"
console.log(reg0);

Bytecode build

  • less size
  • can be slower than js
  • fast build

ASM.js build

  • more size
  • a bit faster than js
  • fast build

WASM build

  • less size
  • much faster than js
  • slow build

About

JavaScript Compiler (babel plugin)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •