Skip to content

Commit

Permalink
[sort-group] first working inlining optimization
Browse files Browse the repository at this point in the history
* Enable inlining for sort-group engine only
  • Loading branch information
indutny committed Dec 1, 2011
1 parent 993822f commit 8b77fc9
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 39 deletions.
2 changes: 1 addition & 1 deletion lib/xjst/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ exports.generate = function generate(ast, options) {
}, { score: Infinity, node: null });

// If apply can be inlined - create subtree
if (apply.state.isInlineable() && false) {
if (apply.state.isInlineable() && options.engine === 'sort-group') {
var fnId = identifier.generate(),
subtree = engine(templates, options, {
state: apply.state.clone(),
Expand Down
83 changes: 45 additions & 38 deletions lib/xjst/engines/sort-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,17 @@ module.exports = function engine(templates, options, config) {
// `switch (tag) { case val: switch (tag2) { ... } }`
var result = { id: id.generate(), state: state.clone() };
tags.reduce(function(result, tag) {
if (result.isInevitable) return result;

var state = result.state,
subgroup = groups[tag[0]].shift(),
tagStr = utils.stringify(tag[1]);
tagStr = utils.stringify(tag[1]),

// Check if we already know tag's value
inevitable = false;

// Create new switch
result['switch'] = tag[1];
result.switchId = tag[0];

// Check if we already know tag's value
var inevitable;

// `subgroup` is a hashmap of possible predicate values
result.cases = Object.keys(subgroup).map(function(key) {
// Do not generate case if inevitable already known
Expand Down Expand Up @@ -198,49 +196,43 @@ module.exports = function engine(templates, options, config) {
if (def) lastDefault.stmt = def[1];
if (!lastDefault.stmt) lastDefault.stmt = errStmt;

if (state.has(tagStr, key)) inevitable = subSwitch;
// If state has tag-value pair set inevitable flag
if (state.has(tagStr, key)) inevitable = true;

return [item.value, subSwitch];
});

// Do not genereate default clause if we already know that
// some case is inevitable
if (!inevitable) {
// Continue branching with unknown value of switch's tag
result['default'] = {
id: id.generate(),
state: xjst.state.create(
state,
tagStr,
[null].concat(values[tagStr].map(function(value) {
return utils.stringify(value);
}).filter(function(value) {
return !subgroup[value];
}))
),
stmt: errStmt
};
// Continue branching with unknown value of switch's tag
result['default'] = {
id: id.generate(),
state: xjst.state.create(
state,
tagStr,
[null].concat(values[tagStr].map(function(value) {
return utils.stringify(value);
}).filter(function(value) {
return !subgroup[value];
}))
),
stmt: errStmt
};

if (state.has(tagStr)) {
// Default clause is inevitable, if we know value and it hasn't matched
inevitable = result['default'];
}
// If we know value and it hasn't matched
if (!inevitable && state.has(tagStr)) {
// Default clause is inevitable
inevitable = true;
}

result.cases = result.cases.filter(function(branch) {
return !!branch;
});

result.inevitable = inevitable;
if (inevitable) {
if (inevitable['switch']) {
return inevitable['default'];
} else {
inevitable.isInevitable = true;
return inevitable;
}
}

return result['default'];
}, result);

return result.inevitable || result;
return result;
}

// Zip nested matches together (like `this.a && this.a.b`)
Expand Down Expand Up @@ -336,6 +328,21 @@ module.exports = function engine(templates, options, config) {
return tree;
}

function replaceInevitables(tree) {
if (!tree['switch']) return tree;

tree.cases = tree.cases.map(function(branch) {
return replaceInevitables(branch);
});
tree['default'] = replaceInevitables(tree['default']);

if (tree.inevitable) {
return tree.cases.length > 0 ? tree.cases[0][1] : tree['default'];
}

return tree;
}

// And longId's to tree's nodes if we're generating merge information
function tag(tree) {
if (tree['switch']) {
Expand All @@ -360,5 +367,5 @@ module.exports = function engine(templates, options, config) {
}

// Compile in functional style
return tag(propagateErrors(group(templates)));
return tag(replaceInevitables(propagateErrors(group(templates))));
};

0 comments on commit 8b77fc9

Please sign in to comment.