performance boost

This commit is contained in:
sanex3339
2016-12-21 01:27:10 +03:00
parent 841b77b3d0
commit d2d5517dd1
9 changed files with 397 additions and 382 deletions
+332 -334
View File
File diff suppressed because it is too large Load Diff
@@ -3,6 +3,7 @@ import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
import { ICustomNodeGroup } from '../../../interfaces/custom-nodes/ICustomNodeGroup';
import { IOptions } from '../../../interfaces/options/IOptions';
import { CustomNodes } from '../../../enums/container/CustomNodes';
import { CustomNodeGroups } from '../../../enums/container/CustomNodeGroups';
@@ -105,7 +106,25 @@ export const customNodesModule: interfaces.ContainerModule = new ContainerModule
// customNode factory
bind<ICustomNode>(ServiceIdentifiers['Factory<ICustomNode>'])
.toFactory<ICustomNode>((context: interfaces.Context) => {
let cachedOptions: IOptions;
return (customNodeName: CustomNodes) => {
if (!cachedOptions) {
cachedOptions = context.container.get<IOptions>(ServiceIdentifiers.IOptions);
}
// we should avoid automatic resolve for custom nodes which will resolve during traverse over AST tree
switch (customNodeName) {
case CustomNodes.BinaryExpressionFunctionNode:
return new BinaryExpressionFunctionNode(cachedOptions);
case CustomNodes.ControlFlowStorageCallNode:
return new ControlFlowStorageCallNode(cachedOptions);
case CustomNodes.ControlFlowStorageNode:
return new ControlFlowStorageNode(cachedOptions);
}
return context.container.getNamed<ICustomNode>(
ServiceIdentifiers.ICustomNode,
customNodeName
@@ -26,7 +26,7 @@ export const storagesModule: interfaces.ContainerModule = new ContainerModule((b
bind<IStorage<ICustomNode>>(ServiceIdentifiers['Factory<IStorage<ICustomNode>>'])
.toFactory<IStorage<ICustomNode>>((context: interfaces.Context) => {
return () => {
return context.container.get<IStorage<ICustomNode>>(ServiceIdentifiers['IStorage<ICustomNode>']);
return new ControlFlowStorage();
};
});
});
@@ -108,7 +108,7 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
const stringArrayStorageId: string = this.stringArrayStorage.getStorageId();
const stringArrayName: string = `_${Utils.hexadecimalPrefix}${stringArrayStorageId}`;
const stringArrayCallsWrapperName: string = `_${Utils.hexadecimalPrefix}${Utils.stringRotate(stringArrayStorageId, 2)}`;
const stringArrayCallsWrapperName: string = `_${Utils.hexadecimalPrefix}${Utils.stringRotate(stringArrayStorageId, 1)}`;
let stringArrayRotateValue: number;
@@ -129,9 +129,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
const controlFlowStorage: IStorage <ICustomNode> = this.controlFlowStorageFactory();
const hostNode: TNodeWithBlockStatement = FunctionControlFlowTransformer.getHostNode(functionNode);
if (!this.controlFlowData.has(hostNode)) {
this.controlFlowData.set(hostNode, controlFlowStorage);
} else {
if (this.controlFlowData.has(hostNode)) {
if (this.hostNodesWithControlFlowNode.indexOf(hostNode) !== -1) {
hostNode.body.shift();
}
@@ -139,23 +137,23 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
const hostControlFlowStorage: IStorage<ICustomNode> = <IStorage<ICustomNode>>this.controlFlowData.get(hostNode);
controlFlowStorage.mergeWith(hostControlFlowStorage, true);
this.controlFlowData.set(hostNode, controlFlowStorage);
}
this.controlFlowData.set(hostNode, controlFlowStorage);
estraverse.replace(functionNode.body, {
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
if (!FunctionControlFlowTransformer.controlFlowReplacersMap.has(node.type)) {
return;
}
if (RandomGeneratorUtils.getRandomFloat(0, 1) > this.options.controlFlowFlatteningThreshold) {
return;
}
const controlFlowReplacerName: NodeControlFlowReplacers | undefined = FunctionControlFlowTransformer
const controlFlowReplacerName: NodeControlFlowReplacers = <NodeControlFlowReplacers>FunctionControlFlowTransformer
.controlFlowReplacersMap.get(node.type);
if (controlFlowReplacerName === undefined) {
return;
}
return {
...this.controlFlowReplacerFactory(controlFlowReplacerName)
.replace(node, parentNode, controlFlowStorage),
@@ -2,7 +2,6 @@ import { injectable, inject } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as escodegen from 'escodegen';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { IOptions } from '../../interfaces/options/IOptions';
@@ -38,24 +37,18 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
* @param memberExpressionNode
*/
public transformNode (memberExpressionNode: ESTree.MemberExpression): void {
estraverse.traverse(memberExpressionNode.property, {
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
if (Node.isLiteralNode(node)) {
this.obfuscateLiteralProperty(node);
if (Node.isLiteralNode(memberExpressionNode.property)) {
memberExpressionNode.property = this.obfuscateLiteralProperty(memberExpressionNode.property);
}
return;
}
if (Node.isIdentifierNode(node)) {
if (memberExpressionNode.computed) {
return;
}
memberExpressionNode.computed = true;
this.obfuscateIdentifierProperty(node);
}
if (Node.isIdentifierNode(memberExpressionNode.property)) {
if (memberExpressionNode.computed) {
return;
}
});
memberExpressionNode.computed = true;
memberExpressionNode.property = this.obfuscateIdentifierProperty(memberExpressionNode.property);
}
}
/**
@@ -69,22 +62,18 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
* object[identifier] = 1;
*
* @param node
* @returns {ESTree.Literal}
*/
private obfuscateIdentifierProperty (node: ESTree.Identifier): void {
const nodeValue: string = node.name;
const literalNode: ESTree.Literal = {
raw: `'${nodeValue}'`,
'x-verbatim-property': {
content: this.stringLiteralReplacer.replace(nodeValue),
precedence: escodegen.Precedence.Primary
},
private obfuscateIdentifierProperty (node: ESTree.Identifier): ESTree.Literal {
return {
type: NodeType.Literal,
value: nodeValue
value: node.name,
raw: `'${node.name}'`,
'x-verbatim-property': {
content: this.stringLiteralReplacer.replace(node.name),
precedence: escodegen.Precedence.Primary
}
};
delete node.name;
Object.assign(node, literalNode);
}
/**
@@ -95,13 +84,16 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
* object[_0x23d45[25]] = 1;
*
* @param node
* @returns {ESTree.Literal}
*/
private obfuscateLiteralProperty (node: ESTree.Literal): void {
private obfuscateLiteralProperty (node: ESTree.Literal): ESTree.Literal {
if (typeof node.value === 'string' && !node['x-verbatim-property']) {
node['x-verbatim-property'] = {
content : this.stringLiteralReplacer.replace(node.value),
content: this.stringLiteralReplacer.replace(node.value),
precedence: escodegen.Precedence.Primary
};
}
return node;
}
}
@@ -103,7 +103,7 @@ export class StringLiteralReplacer extends AbstractReplacer {
this.stringArrayStorage.set(null, value);
}
const rotatedStringArrayStorageId: string = Utils.stringRotate(this.stringArrayStorage.getStorageId(), 2);
const rotatedStringArrayStorageId: string = Utils.stringRotate(this.stringArrayStorage.getStorageId(), 1);
const stringArrayStorageCallsWrapperName: string = `_${Utils.hexadecimalPrefix}${rotatedStringArrayStorageId}`;
const hexadecimalIndex: string = `${Utils.hexadecimalPrefix}${Utils.decToHex(indexOfValue)}`;
+1 -1
View File
@@ -47,7 +47,7 @@ export abstract class MapStorage <T> implements IStorage <T> {
* @returns {number}
*/
public getLength (): number {
return Array.from(this.storage).length;
return this.storage.size;
}
/**
+10 -2
View File
@@ -98,7 +98,15 @@ export class Utils {
* @returns {string}
*/
public static stringRotate (string: string, times: number): string {
return Utils.arrayRotate(Array.from(string), times).join('');
if (!string) {
throw new ReferenceError(`Cannot rotate empty string.`);
}
for (let i = 0; i < times; i++) {
string = string[string.length - 1] + string.substring(0, string.length - 1);
}
return string;
}
/**
@@ -133,7 +141,7 @@ export class Utils {
prefix = '\\u';
template = '0'.repeat(4);
}
return `${prefix}${(template + escape.charCodeAt(0).toString(radix)).slice(-template.length)}`;
})}`;
}