Skip to content

Commit

Permalink
Fixed comma optimizer
Browse files Browse the repository at this point in the history
  • Loading branch information
fasttime committed Oct 16, 2020
1 parent 893d250 commit d6e037e
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 82 deletions.
70 changes: 37 additions & 33 deletions lib/jscrewit.js
Original file line number Diff line number Diff line change
Expand Up @@ -1960,7 +1960,7 @@
return entry;
}

// novem 1.0.0 – https://github.com/fasttime/novem
// novem 1.1.0 – https://github.com/fasttime/novem

var INVALID_EXPR = {};
function doEval(expr) {
Expand Down Expand Up @@ -3539,7 +3539,6 @@
Object: define({ expr: 'Object.name', optimize: { toStringOpt: true } }, NAME),
RegExp: define({ expr: 'RegExp.name', optimize: { toStringOpt: true } }, NAME),
String: define('String.name', NAME),
'f,a,l,s,e': define({ expr: 'F_A_L_S_E', solutionType: SolutionType.OBJECT }),
fromCharCo:
define({ expr: '"from3har3o".split(3).join("C")', optimize: { toStringOpt: true } }),
mCh: define('atob("bUNo")', Feature.ATOB),
Expand Down Expand Up @@ -4149,8 +4148,7 @@
20:
[
define(10),
define
({ block: 'RP_6_SO', indexer: 3 + ' + FH_SHIFT_1' }, NO_V8_SRC),
define({ block: 'RP_6_SO', indexer: 3 + ' + FH_SHIFT_1' }, NO_V8_SRC),
define(0, V8_SRC),
define(5, IE_SRC),
define(6, FF_SRC),
Expand All @@ -4176,8 +4174,7 @@
30:
[
define(10),
define
({ block: 'RP_6_SO', indexer: 4 + ' + FH_SHIFT_1' }, NO_V8_SRC),
define({ block: 'RP_6_SO', indexer: 4 + ' + FH_SHIFT_1' }, NO_V8_SRC),
define(0, V8_SRC),
define(5, IE_SRC),
define(6, FF_SRC),
Expand Down Expand Up @@ -7313,10 +7310,9 @@
);
var source = bridgeChars.join();
var bridge = bridgeChars.join('');
var optimizerList = encoder.getOptimizerList(bridge, true);
var buffer = new ScrewBuffer(SCREW_AS_STRING, bridgeSolutions.length, optimizerList);
bridgeSolutions.forEach(buffer.append);
var replacement = rampReplacement + '(' + buffer + ')';
var bridgeReplacement =
encoder.replaceString(bridge, { optimize: true, screwMode: SCREW_AS_STRING });
var replacement = rampReplacement + '(' + bridgeReplacement + ')';
var solution = new SimpleSolution(source, replacement, SolutionType.OBJECT);
return solution;
};
Expand All @@ -7325,34 +7321,42 @@

function optimizeSolutions(plan, solutions, bond, forceString)
{
var solutionCount = solutions.length;
for (var index = 0, end = solutionCount - 2; index < end;)
function passFrom(index)
{
var commaCount = countClusterableCommas(solutions, index);
if (commaCount)
while (index < end)
{
var clusterLength = 2 * commaCount + 1;
var saving = getCommaAppendLength(solutions, index, clusterLength) - extraLength;
var singlePart = !index && clusterLength === solutionCount;
if (singlePart)
{
if (forceString)
saving -= 3; // "+[]"
else if (bond)
saving += 2; // "(" + ")"
}
if (index && solutions[index].isWeak)
saving += 2; // Save a pair of parentheses.
if (saving > 0)
var commaCount = countClusterableCommas(solutions, index);
if (commaCount)
{
var clusterer = createClusterer(solutions, index, commaCount);
plan.addCluster(index, clusterLength, clusterer, saving);
var clusterLength = 2 * commaCount + 1;
var saving =
getCommaAppendLength(solutions, index, clusterLength) - extraLength;
var singlePart = !index && clusterLength === solutionCount;
if (singlePart)
{
if (forceString)
saving -= 3; // "+[]"
else if (bond)
saving += 2; // "(" + ")"
}
if (index && solutions[index].isWeak)
saving += 2; // Save a pair of parentheses.
if (saving > 0)
{
var clusterer = createClusterer(solutions, index, commaCount);
plan.addCluster(index, clusterLength, clusterer, saving);
}
index += clusterLength + 1;
}
index += clusterLength;
else
index += 2;
}
else
++index;
}

var solutionCount = solutions.length;
var end = solutionCount - 2;
passFrom(0);
passFrom(1);
}

var rampReplacement = encoder.replaceExpr('[][SLICE_OR_FLAT].call');
Expand Down Expand Up @@ -7716,7 +7720,7 @@
var optimizeToString;
if (typeof optimize === 'object')
{
optimizeComma = !!optimize.comma;
optimizeComma = !!optimize.commaOpt;
optimizeComplex = !!optimize.complexOpt;
optimizeToString = !!optimize.toStringOpt;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/jscrewit.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"handlebars": "latest",
"mocha": "3",
"mocha-bar": "latest",
"novem": "1.0",
"novem": "1.1",
"postrequire": "latest",
"rollup": "latest",
"rollup-plugin-cleanup": "latest",
Expand Down
7 changes: 2 additions & 5 deletions src/lib/definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,6 @@ export var initReplaceStaticExpr;
Object: define({ expr: 'Object.name', optimize: { toStringOpt: true } }, NAME),
RegExp: define({ expr: 'RegExp.name', optimize: { toStringOpt: true } }, NAME),
String: define('String.name', NAME),
'f,a,l,s,e': define({ expr: 'F_A_L_S_E', solutionType: SolutionType.OBJECT }),
fromCharCo:
define({ expr: '"from3har3o".split(3).join("C")', optimize: { toStringOpt: true } }),
mCh: define('atob("bUNo")', Feature.ATOB),
Expand Down Expand Up @@ -1745,8 +1744,7 @@ export var initReplaceStaticExpr;
20:
[
define(10),
define
({ block: 'RP_6_SO', indexer: 3 + ' + FH_SHIFT_1' }, NO_V8_SRC),
define({ block: 'RP_6_SO', indexer: 3 + ' + FH_SHIFT_1' }, NO_V8_SRC),
define(0, V8_SRC),
define(5, IE_SRC),
define(6, FF_SRC),
Expand All @@ -1772,8 +1770,7 @@ export var initReplaceStaticExpr;
30:
[
define(10),
define
({ block: 'RP_6_SO', indexer: 4 + ' + FH_SHIFT_1' }, NO_V8_SRC),
define({ block: 'RP_6_SO', indexer: 4 + ' + FH_SHIFT_1' }, NO_V8_SRC),
define(0, V8_SRC),
define(5, IE_SRC),
define(6, FF_SRC),
Expand Down
2 changes: 1 addition & 1 deletion src/lib/optimizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import createToStringOptimizer from './optimizers/to-string-optimizer';
var optimizeToString;
if (typeof optimize === 'object')
{
optimizeComma = !!optimize.comma;
optimizeComma = !!optimize.commaOpt;
optimizeComplex = !!optimize.complexOpt;
optimizeToString = !!optimize.toStringOpt;
}
Expand Down
65 changes: 36 additions & 29 deletions src/lib/optimizers/comma-optimizer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SCREW_AS_STRING, ScrewBuffer } from '../screw-buffer';
import { SimpleSolution } from '../solution';
import { SolutionType } from 'novem';
import { SCREW_AS_STRING } from '../screw-buffer';
import { SimpleSolution } from '../solution';
import { SolutionType } from 'novem';

function appendLengthOf(solution)
{
Expand Down Expand Up @@ -63,10 +63,9 @@ export default function (encoder)
);
var source = bridgeChars.join();
var bridge = bridgeChars.join('');
var optimizerList = encoder.getOptimizerList(bridge, true);
var buffer = new ScrewBuffer(SCREW_AS_STRING, bridgeSolutions.length, optimizerList);
bridgeSolutions.forEach(buffer.append);
var replacement = rampReplacement + '(' + buffer + ')';
var bridgeReplacement =
encoder.replaceString(bridge, { optimize: true, screwMode: SCREW_AS_STRING });
var replacement = rampReplacement + '(' + bridgeReplacement + ')';
var solution = new SimpleSolution(source, replacement, SolutionType.OBJECT);
return solution;
};
Expand All @@ -75,34 +74,42 @@ export default function (encoder)

function optimizeSolutions(plan, solutions, bond, forceString)
{
var solutionCount = solutions.length;
for (var index = 0, end = solutionCount - 2; index < end;)
function passFrom(index)
{
var commaCount = countClusterableCommas(solutions, index);
if (commaCount)
while (index < end)
{
var clusterLength = 2 * commaCount + 1;
var saving = getCommaAppendLength(solutions, index, clusterLength) - extraLength;
var singlePart = !index && clusterLength === solutionCount;
if (singlePart)
{
if (forceString)
saving -= 3; // "+[]"
else if (bond)
saving += 2; // "(" + ")"
}
if (index && solutions[index].isWeak)
saving += 2; // Save a pair of parentheses.
if (saving > 0)
var commaCount = countClusterableCommas(solutions, index);
if (commaCount)
{
var clusterer = createClusterer(solutions, index, commaCount);
plan.addCluster(index, clusterLength, clusterer, saving);
var clusterLength = 2 * commaCount + 1;
var saving =
getCommaAppendLength(solutions, index, clusterLength) - extraLength;
var singlePart = !index && clusterLength === solutionCount;
if (singlePart)
{
if (forceString)
saving -= 3; // "+[]"
else if (bond)
saving += 2; // "(" + ")"
}
if (index && solutions[index].isWeak)
saving += 2; // Save a pair of parentheses.
if (saving > 0)
{
var clusterer = createClusterer(solutions, index, commaCount);
plan.addCluster(index, clusterLength, clusterer, saving);
}
index += clusterLength + 1;
}
index += clusterLength;
else
index += 2;
}
else
++index;
}

var solutionCount = solutions.length;
var end = solutionCount - 2;
passFrom(0);
passFrom(1);
}

var rampReplacement = encoder.replaceExpr('[][SLICE_OR_FLAT].call');
Expand Down
66 changes: 54 additions & 12 deletions test/lib/optimizers/comma-optimizer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,27 @@
{
var encoder =
{
getOptimizerList:
function ()
{
return [];
},
replaceExpr:
function ()
{
return '[].slice.call';
},
replaceString:
function (str, options)
{
expect(options.optimize).toBe(true);
var solution = new DynamicSolution();
Array.prototype.forEach.call
(
str,
function (char)
{
var subSolution = SOLUTIONS[char];
solution.append(subSolution);
}
);
return solution.replacement;
},
};
var optimizer = JScrewIt.debug.createCommaOptimizer(encoder);
return optimizer;
Expand All @@ -27,6 +38,7 @@
var JScrewIt =
typeof module !== 'undefined' ? require('../../node-jscrewit-test') : self.JScrewIt;

var DynamicSolution = JScrewIt.debug.DynamicSolution;
var Solution = JScrewIt.debug.Solution;
var SolutionType = JScrewIt.debug.SolutionType;

Expand All @@ -44,11 +56,11 @@
new Solution
('C', '"C"', SolutionType.STRING),

COMMA:
',':
new Solution
(',', '([].slice.call(![]+[])+[])[+!![]]', SolutionType.STRING),

ZERO:
0:
new Solution
('0', '+![]', SolutionType.WEAK_ALGEBRAIC),

Expand All @@ -73,7 +85,7 @@
function ()
{
var optimizer = createOptimizer();
var actual = optimizer.appendLengthOf(SOLUTIONS.COMMA);
var actual = optimizer.appendLengthOf(SOLUTIONS[',']);
expect(actual).toBe(0);
}
);
Expand Down Expand Up @@ -106,7 +118,7 @@
var initSolutions =
function ()
{
solutions = [SOLUTIONS.A, SOLUTIONS.COMMA, SOLUTIONS.B];
solutions = [SOLUTIONS.A, SOLUTIONS[','], SOLUTIONS.B];
};

// OK.
Expand Down Expand Up @@ -154,9 +166,9 @@
solutions =
[
SOLUTIONS.A,
SOLUTIONS.COMMA,
SOLUTIONS[','],
SOLUTIONS.B,
SOLUTIONS.COMMA,
SOLUTIONS[','],
SOLUTIONS.C,
];
};
Expand All @@ -181,6 +193,36 @@
expect(solutions.length).toBeGreaterThan(1);
}
);
it
(
'optimizes adjacent commas',
function ()
{
var optimizer = createOptimizer();
var solutions;
var initSolutions =
function ()
{
solutions =
[
SOLUTIONS.A,
SOLUTIONS[','],
SOLUTIONS[','],
SOLUTIONS.B,
SOLUTIONS[','],
SOLUTIONS.C,
];
};

// OK.
initSolutions();
optimizeSolutions([optimizer], solutions, false, false);
expect(solutions.length).toBe(2);
expect(solutions[1].replacement)
.toBe('[].slice.call(' + SOLUTIONS[','].replacement + '+"B"+"C")');
expect(solutions[1].type).toBe(SolutionType.OBJECT);
}
);
describe
(
'does not optimize a comma in a single part because of string forcing',
Expand Down Expand Up @@ -315,7 +357,7 @@
function ()
{
solutions =
[SOLUTIONS.false, SOLUTIONS.ZERO, COMMA_SOLUTION, SOLUTIONS.A];
[SOLUTIONS.false, SOLUTIONS[0], COMMA_SOLUTION, SOLUTIONS.A];
};

// OK.
Expand Down

0 comments on commit d6e037e

Please sign in to comment.