compile preformance fix

This commit is contained in:
sanex3339
2016-10-30 22:31:59 +03:00
parent 07fbe7202c
commit a2cbfe4ae5
21 changed files with 76699 additions and 187 deletions
+1
View File
@@ -0,0 +1 @@
test/fixtures/compile-performance.js
+43 -53
View File
@@ -88,7 +88,7 @@ module.exports =
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 84);
/******/ return __webpack_require__(__webpack_require__.s = 85);
/******/ })
/************************************************************************/
/******/ ([
@@ -888,16 +888,11 @@ var CustomNodeAppender = function () {
NodeUtils_1.NodeUtils.prependNode(targetBlockScopeBody, node);
}
}, {
key: 'getIndexByThreshold',
value: function getIndexByThreshold(blockStatementBodyLength) {
var threshold = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.1;
if (threshold < 0 || threshold > 1) {
throw new RangeError('`threshold` parameter should has value between 0 and 1');
}
key: 'getRandomStackTraceIndex',
value: function getRandomStackTraceIndex(stackTraceRootLength) {
return Utils_1.Utils.getRandomGenerator().integer({
min: 0,
max: Math.round((blockStatementBodyLength - 1) * threshold)
max: Math.max(0, Math.round(stackTraceRootLength - 1))
});
}
}, {
@@ -1797,7 +1792,7 @@ var ConsoleOutputDisableExpressionNode = function (_AbstractCustomNode_) {
_createClass(ConsoleOutputDisableExpressionNode, [{
key: 'appendNode',
value: function appendNode(blockScopeNode, stackTraceData) {
CustomNodeAppender_1.CustomNodeAppender.appendNode(stackTraceData, blockScopeNode.body, this.getNode(), CustomNodeAppender_1.CustomNodeAppender.getIndexByThreshold(blockScopeNode.body.length));
CustomNodeAppender_1.CustomNodeAppender.appendNode(stackTraceData, blockScopeNode.body, this.getNode(), CustomNodeAppender_1.CustomNodeAppender.getRandomStackTraceIndex(stackTraceData.length));
}
}, {
key: 'getNodeStructure',
@@ -2021,7 +2016,7 @@ var DomainLockNode = function (_AbstractCustomNode_) {
_createClass(DomainLockNode, [{
key: 'appendNode',
value: function appendNode(blockScopeNode, stackTraceData) {
CustomNodeAppender_1.CustomNodeAppender.appendNode(stackTraceData, blockScopeNode.body, this.getNode(), CustomNodeAppender_1.CustomNodeAppender.getIndexByThreshold(blockScopeNode.body.length));
CustomNodeAppender_1.CustomNodeAppender.appendNode(stackTraceData, blockScopeNode.body, this.getNode(), CustomNodeAppender_1.CustomNodeAppender.getRandomStackTraceIndex(stackTraceData.length));
}
}, {
key: 'getNodeStructure',
@@ -2084,7 +2079,7 @@ var SelfDefendingUnicodeNode = function (_AbstractCustomNode_) {
_createClass(SelfDefendingUnicodeNode, [{
key: 'appendNode',
value: function appendNode(blockScopeNode, stackTraceData) {
CustomNodeAppender_1.CustomNodeAppender.appendNode(stackTraceData, blockScopeNode.body, this.getNode(), CustomNodeAppender_1.CustomNodeAppender.getIndexByThreshold(blockScopeNode.body.length));
CustomNodeAppender_1.CustomNodeAppender.appendNode(stackTraceData, blockScopeNode.body, this.getNode(), CustomNodeAppender_1.CustomNodeAppender.getRandomStackTraceIndex(stackTraceData.length));
}
}, {
key: 'getNodeStructure',
@@ -3570,58 +3565,52 @@ var StackTraceAnalyzer = function () {
value: function analyzeRecursive(blockScopeBody) {
var _this = this;
var limitIndex = StackTraceAnalyzer.getLimitIndex(blockScopeBody.length);
var stackTraceData = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
var _loop = function _loop() {
var rootNode = _step.value;
estraverse.traverse(rootNode, {
enter: function enter(node) {
if (!Nodes_1.Nodes.isCallExpressionNode(node) || rootNode.parentNode !== NodeUtils_1.NodeUtils.getBlockScopeOfNode(node)) {
blockScopeBody.forEach(function (rootNode, index) {
if (index > limitIndex) {
return;
}
estraverse.traverse(rootNode, {
enter: function enter(node) {
if (!Nodes_1.Nodes.isCallExpressionNode(node) || rootNode.parentNode !== NodeUtils_1.NodeUtils.getBlockScopeOfNode(node)) {
return;
}
_this.calleeDataExtractors.forEach(function (calleeDataExtractor) {
var calleeData = new calleeDataExtractor(blockScopeBody, node.callee).extract();
if (!calleeData) {
return;
}
_this.calleeDataExtractors.forEach(function (calleeDataExtractor) {
var calleeData = new calleeDataExtractor(blockScopeBody, node.callee).extract();
if (!calleeData) {
return;
}
stackTraceData.push(Object.assign({}, calleeData, {
stackTrace: _this.analyzeRecursive(calleeData.callee.body)
}));
});
}
});
};
for (var _iterator = blockScopeBody[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
_loop();
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
stackTraceData.push(Object.assign({}, calleeData, {
stackTrace: _this.analyzeRecursive(calleeData.callee.body)
}));
});
}
});
});
return stackTraceData;
}
}], [{
key: 'getLimitIndex',
value: function getLimitIndex(blockScopeBodyLength) {
var lastIndex = blockScopeBodyLength - 1;
var limitThresholdActivationIndex = StackTraceAnalyzer.limitThresholdActivationLength - 1;
var limitIndex = lastIndex;
if (lastIndex > limitThresholdActivationIndex) {
limitIndex = Math.round(limitThresholdActivationIndex + lastIndex * StackTraceAnalyzer.limitThreshold);
if (limitIndex > lastIndex) {
limitIndex = lastIndex;
}
}
return stackTraceData;
return limitIndex;
}
}]);
return StackTraceAnalyzer;
}();
StackTraceAnalyzer.limitThresholdActivationLength = 25;
StackTraceAnalyzer.limitThreshold = 0.1;
exports.StackTraceAnalyzer = StackTraceAnalyzer;
/***/ },
@@ -4106,7 +4095,8 @@ module.exports = require("fs");
module.exports = require("mkdirp");
/***/ },
/* 84 */
/* 84 */,
/* 85 */
/***/ function(module, exports, __webpack_require__) {
"use strict";
+2 -1
View File
@@ -71,7 +71,8 @@
"watch": "scripts/watch",
"test:compile": "scripts/test-compile",
"test:dev": "scripts/test-dev",
"test:devPerformance": "scripts/test-dev-performance",
"test:devCompilePerformance": "scripts/test-dev-compile-performance",
"test:devRuntimePerformance": "scripts/test-dev-runtime-performance",
"test:full": "scripts/test-full",
"test:coveralls": "scripts/test-coveralls",
"test:mocha": "scripts/test-mocha",
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/bash
$(npm bin)/ts-node test/dev/test.ts
$(npm bin)/ts-node test/dev/dev.ts
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
$(npm bin)/ts-node test/dev/dev-compile-performance.ts
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
$(npm bin)/ts-node test/dev/test-performance.ts
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
$(npm bin)/ts-node test/dev/dev-runtime-performance.ts
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
npm run test:compile &&
node test-tmp/test/dev/test.js &&
node test-tmp/test/dev/dev.js &&
$(npm bin)/istanbul cover $(npm bin)/_mocha -- test-tmp/test/index.spec.js &&
npm run test:removeTmpDir
+3 -8
View File
@@ -47,17 +47,12 @@ export class CustomNodeAppender {
}
/**
* @param blockStatementBodyLength
* @param threshold
* @param stackTraceRootLength
*/
public static getIndexByThreshold (blockStatementBodyLength: number, threshold: number = 0.1): number {
if (threshold < 0 || threshold > 1) {
throw new RangeError('`threshold` parameter should has value between 0 and 1');
}
public static getRandomStackTraceIndex (stackTraceRootLength: number): number {
return Utils.getRandomGenerator().integer({
min: 0,
max: Math.round((blockStatementBodyLength - 1) * threshold)
max: Math.max(0, Math.round(stackTraceRootLength - 1))
});
}
@@ -27,7 +27,7 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
stackTraceData,
blockScopeNode.body,
this.getNode(),
CustomNodeAppender.getIndexByThreshold(blockScopeNode.body.length)
CustomNodeAppender.getRandomStackTraceIndex(stackTraceData.length)
);
}
@@ -30,7 +30,7 @@ export class DomainLockNode extends AbstractCustomNode {
stackTraceData,
blockScopeNode.body,
this.getNode(),
CustomNodeAppender.getIndexByThreshold(blockScopeNode.body.length)
CustomNodeAppender.getRandomStackTraceIndex(stackTraceData.length)
);
}
@@ -30,7 +30,7 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
stackTraceData,
blockScopeNode.body,
this.getNode(),
CustomNodeAppender.getIndexByThreshold(blockScopeNode.body.length)
CustomNodeAppender.getRandomStackTraceIndex(stackTraceData.length)
);
}
+40 -2
View File
@@ -48,6 +48,16 @@ import { NodeUtils } from '../NodeUtils';
* ]
*/
export class StackTraceAnalyzer implements IStackTraceAnalyzer {
/**
* @type {number}
*/
private static limitThresholdActivationLength: number = 25;
/**
* @type {number}
*/
private static limitThreshold: number = 0.1;
/**
* @type {ESTree.Node[]}
*/
@@ -62,6 +72,29 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer {
[NodeType.ObjectExpression, ObjectExpressionCalleeDataExtractor]
]);
/**
* @param blockScopeBodyLength
* @returns {number}
*/
public static getLimitIndex (blockScopeBodyLength: number): number {
const lastIndex: number = blockScopeBodyLength - 1;
const limitThresholdActivationIndex: number = StackTraceAnalyzer.limitThresholdActivationLength - 1;
let limitIndex: number = lastIndex;
if (lastIndex > limitThresholdActivationIndex) {
limitIndex = Math.round(
limitThresholdActivationIndex + (lastIndex * StackTraceAnalyzer.limitThreshold)
);
if (limitIndex > lastIndex) {
limitIndex = lastIndex;
}
}
return limitIndex;
}
/**
* @param blockScopeBody
*/
@@ -81,9 +114,14 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer {
* @returns {IStackTraceData[]}
*/
private analyzeRecursive (blockScopeBody: ESTree.Node[]): IStackTraceData[] {
const limitIndex: number = StackTraceAnalyzer.getLimitIndex(blockScopeBody.length);
const stackTraceData: IStackTraceData[] = [];
for (const rootNode of blockScopeBody) {
blockScopeBody.forEach((rootNode, index) => {
if (index > limitIndex) {
return;
}
estraverse.traverse(rootNode, {
enter: (node: ESTree.Node): any => {
if (!Nodes.isCallExpressionNode(node) || rootNode.parentNode !== NodeUtils.getBlockScopeOfNode(node)) {
@@ -106,7 +144,7 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer {
});
}
});
}
});
return stackTraceData;
}
+19
View File
@@ -0,0 +1,19 @@
'use strict';
import * as fs from 'fs';
if (!(<any>global)._babelPolyfill) {
require('babel-polyfill');
}
(function () {
const JavaScriptObfuscator: any = require("../../index");
let start: any = new Date();
JavaScriptObfuscator.obfuscate(
fs.readFileSync('test/fixtures/compile-performance.js', 'utf8')
).getObfuscatedCode();
console.log(`Total time: ${<any>new Date() - start}`);
})();
+84
View File
@@ -0,0 +1,84 @@
'use strict';
if (!(<any>global)._babelPolyfill) {
require('babel-polyfill');
}
(function () {
const JavaScriptObfuscator: any = require("../../index");
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`
var start = new Date();
var log = console.log;
console.log = function () {};
${String(`
var result = 1,
term1 = 0,
term2 = 1,
i = 1;
while(i < 10)
{
var test = 10;
result = term1 + term2;
console.log(result);
term1 = term2;
term2 = result;
i++;
}
console.log(test);
var test = function (test) {
console.log(test);
if (true) {
var test = 5
}
return test;
}
console.log(test(1));
function test2 (abc) {
function test1 () {
console.log('inside', abc.item);
}
console.log('тест', abc);
var abc = {};
return abc.item = 15, test1();
};
var regexptest = /version\\/(\\d+)/i;
console.log(regexptest);
test2(22);
console.log(105.4);
console.log(true, false);
var sA = 'shorthand1';
var sB = 'shorthand2';
console.log({sA, sB});
try {
} catch (error) {
console.log(error);
}
`).repeat(200)}
console.log = log;
console.log(new Date() - start);
`,
{
disableConsoleOutput: false,
}
).getObfuscatedCode();
console.log(eval(obfuscatedCode));
})();
+12 -10
View File
@@ -4,10 +4,11 @@ if (!(<any>global)._babelPolyfill) {
require('babel-polyfill');
}
const JavaScriptObfuscator: any = require("../../index");
(function () {
const JavaScriptObfuscator: any = require("../../index");
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`
(function(){
var result = 1,
term1 = 0,
@@ -67,11 +68,12 @@ let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
}
})();
`,
{
disableConsoleOutput: false,
unicodeArrayEncoding: 'rc4'
}
).getObfuscatedCode();
{
disableConsoleOutput: false,
unicodeArrayEncoding: 'rc4'
}
).getObfuscatedCode();
console.log(obfuscatedCode);
console.log(eval(obfuscatedCode));
console.log(obfuscatedCode);
console.log(eval(obfuscatedCode));
})();
-87
View File
@@ -1,87 +0,0 @@
'use strict';
if (!(<any>global)._babelPolyfill) {
require('babel-polyfill');
}
const JavaScriptObfuscator: any = require("../../index");
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`
(function (){
var start = new Date();
var log = console.log;
console.log = function () {};
(function(){
${String(`
var result = 1,
term1 = 0,
term2 = 1,
i = 1;
while(i < 10)
{
var test = 10;
result = term1 + term2;
console.log(result);
term1 = term2;
term2 = result;
i++;
}
console.log(test);
var test = function (test) {
console.log(test);
if (true) {
var test = 5
}
return test;
}
console.log(test(1));
function test2 (abc) {
function test1 () {
console.log('inside', abc.item);
}
console.log('тест', abc);
var abc = {};
return abc.item = 15, test1();
};
var regexptest = /version\\/(\\d+)/i;
console.log(regexptest);
test2(22);
console.log(105.4);
console.log(true, false);
var sA = 'shorthand1';
var sB = 'shorthand2';
console.log({sA, sB});
try {
} catch (error) {
console.log(error);
}
`).repeat(1000)}
})();
console.log = log;
console.log(new Date() - start);
})();
`,
{
disableConsoleOutput: false,
unicodeArrayEncoding: 'rc4'
}
).getObfuscatedCode();
console.log(eval(obfuscatedCode));
File diff suppressed because it is too large Load Diff
+1
View File
@@ -17,6 +17,7 @@ import './unit-tests/custom-nodes/CustomNodeAppender.spec';
import './unit-tests/node-obfuscators/CatchClauseObfuscator.spec';
import './unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec';
import './unit-tests/node-obfuscators/FunctionObfuscator.spec';
import './unit-tests/stack-trace-analyzer/StackTraceAnalyzer.spec';
/**
* Functional tests
@@ -278,31 +278,91 @@ describe('CustomNodeAppender', () => {
assert.deepEqual(astTree, expectedAstTree);
});
it('should append node into deepest function call by specified index in calls trace - variant #3', () => {
astTree = <ESTree.Program>NodeUtils.convertCodeToStructure(`
var start = new Date();
var log = console.log;
console.log = function () {};
(function () {
function bar () {
function inner1 () {
}
function inner2 () {
var inner3 = function () {
}
inner3();
}
inner2();
inner1();
}
bar();
})();
console.log = log;
console.log(new Date() - start);
`, false);
expectedAstTree = <ESTree.Program>NodeUtils.convertCodeToStructure(`
var start = new Date();
var log = console.log;
console.log = function () {};
(function () {
function bar () {
function inner1 () {
}
function inner2 () {
var inner3 = function () {
var test = 1;
}
inner3();
}
inner2();
inner1();
}
bar();
})();
console.log = log;
console.log(new Date() - start);
`, false);
stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
CustomNodeAppender.appendNode(
stackTraceData,
astTree.body,
node,
CustomNodeAppender.getRandomStackTraceIndex(stackTraceData.length)
);
NodeUtils.parentize(astTree);
assert.deepEqual(astTree, expectedAstTree);
});
});
});
describe('getIndexByThreshold (blockStatementBodyLength: number, threshold: number = 0.1): number', () => {
it('should returns random index between 0 and index based on threshold value', () => {
describe('getRandomStackTraceIndex (stackTraceRootLength: number): number', () => {
it('should returns random index between 0 and stack trace deata root length', () => {
let index: number;
for (let i: number = 0; i < 10; i++) {
index = CustomNodeAppender.getIndexByThreshold(100, 0.1);
for (let i: number = 0; i < 100; i++) {
index = CustomNodeAppender.getRandomStackTraceIndex(100);
assert.isAtLeast(index, 0);
assert.isAtMost(index, 10);
}
for (let i: number = 0; i < 10; i++) {
index = CustomNodeAppender.getIndexByThreshold(10, 0.5);
assert.isAtLeast(index, 0);
assert.isAtMost(index, 5);
}
for (let i: number = 0; i < 10; i++) {
index = CustomNodeAppender.getIndexByThreshold(1, 1);
assert.equal(index, 0);
assert.isAtMost(index, 100);
}
});
});
@@ -0,0 +1,23 @@
import * as chai from 'chai';
import { StackTraceAnalyzer } from '../../../src/stack-trace-analyzer/StackTraceAnalyzer';
const assert: any = chai.assert;
describe('StackTraceAnalyzer', () => {
describe('getLimitIndex (blockScopeBodyLength: number): number', () => {
it('should returns correct limit index based on block scope body length', () => {
const blockScopeBodyLength1: number = 100;
const blockScopeBodyLength2: number = 22;
const blockScopeBodyLength3: number = 26;
const blockScopeBodyLength4: number = 28;
const blockScopeBodyLength5: number = 34;
assert.equal(StackTraceAnalyzer.getLimitIndex(blockScopeBodyLength1), 34);
assert.equal(StackTraceAnalyzer.getLimitIndex(blockScopeBodyLength2), 21);
assert.equal(StackTraceAnalyzer.getLimitIndex(blockScopeBodyLength3), 25);
assert.equal(StackTraceAnalyzer.getLimitIndex(blockScopeBodyLength4), 27);
assert.equal(StackTraceAnalyzer.getLimitIndex(blockScopeBodyLength5), 27);
});
});
});