diff --git a/lib/parser_inline.js b/lib/parser_inline.js index abc4edd..cd30260 100644 --- a/lib/parser_inline.js +++ b/lib/parser_inline.js @@ -61,18 +61,18 @@ ParserInline.prototype.rulesUpdate = function () { // returns `true` if any rule reported success // ParserInline.prototype.skipToken = function (state) { - var i, pos = state.pos, + var i, cached_pos, pos = state.pos, rules = this._rules, len = this._rules.length; - if (state.cache[pos] !== undefined) { - state.pos = state.cache[pos]; + if ((cached_pos = state.cacheGet(pos)) > 0) { + state.pos = cached_pos; return true; } for (i = 0; i < len; i++) { if (rules[i](state, true)) { - state.cache[pos] = state.pos; + state.cacheSet(pos, state.pos); return true; } } diff --git a/lib/rules_inline/state_inline.js b/lib/rules_inline/state_inline.js index 723833e..5a85bb0 100644 --- a/lib/rules_inline/state_inline.js +++ b/lib/rules_inline/state_inline.js @@ -15,7 +15,7 @@ function StateInline(src, parser, options, env) { this.pending = ''; this.pendingLevel = 0; - this.cache = {}; // Stores { start: end } pairs. Useful for backtrack + this.cache = []; // Stores { start: end } pairs. Useful for backtrack // optimization of pairs parse (emphasis, strikes). // Link parser state vars @@ -34,6 +34,8 @@ function StateInline(src, parser, options, env) { } +// Flush pending text +// StateInline.prototype.pushPending = function () { this.tokens.push({ type: 'text', @@ -43,6 +45,10 @@ StateInline.prototype.pushPending = function () { this.pending = ''; }; + +// Push new token to "stream". +// If pending text exists - flush it as text token +// StateInline.prototype.push = function (token) { if (this.pending) { this.pushPending(); @@ -53,4 +59,24 @@ StateInline.prototype.push = function (token) { }; +// Store value to cache. +// !!! Implementation has parser-specific optimizations +// !!! keys MUST be integer, >= 0; values MUST be integer, > 0 +// +StateInline.prototype.cacheSet = function (key, val) { + for (var i = this.cache.length; i <= key; i++) { + this.cache.push(0); + } + + this.cache[key] = val; +}; + + +// Get cache value +// +StateInline.prototype.cacheGet = function (key) { + return key < this.cache.length ? this.cache[key] : 0; +}; + + module.exports = StateInline;