mirror of
https://github.com/gorhill/uBlock.git
synced 2025-01-31 20:21:35 +01:00
Fine-tune new bidi-trie code
Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/761
This commit is contained in:
parent
49fb98dcb2
commit
a69b301d81
@ -39,7 +39,14 @@ vAPI.cantWebsocket =
|
|||||||
browser.webRequest.ResourceType instanceof Object === false ||
|
browser.webRequest.ResourceType instanceof Object === false ||
|
||||||
browser.webRequest.ResourceType.WEBSOCKET !== 'websocket';
|
browser.webRequest.ResourceType.WEBSOCKET !== 'websocket';
|
||||||
|
|
||||||
|
vAPI.canWASM = vAPI.webextFlavor.soup.has('chromium') === false;
|
||||||
|
if ( vAPI.canWASM === false ) {
|
||||||
|
const csp = manifest.content_security_policy;
|
||||||
|
vAPI.canWASM = csp !== undefined && csp.indexOf("'wasm-eval'") !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
vAPI.supportsUserStylesheets = vAPI.webextFlavor.soup.has('user_stylesheet');
|
vAPI.supportsUserStylesheets = vAPI.webextFlavor.soup.has('user_stylesheet');
|
||||||
|
|
||||||
// The real actual webextFlavor value may not be set in stone, so listen
|
// The real actual webextFlavor value may not be set in stone, so listen
|
||||||
// for possible future changes.
|
// for possible future changes.
|
||||||
window.addEventListener('webextFlavor', function() {
|
window.addEventListener('webextFlavor', function() {
|
||||||
|
@ -142,7 +142,7 @@ const µBlock = (( ) => { // jshint ignore:line
|
|||||||
// Read-only
|
// Read-only
|
||||||
systemSettings: {
|
systemSettings: {
|
||||||
compiledMagic: 23, // Increase when compiled format changes
|
compiledMagic: 23, // Increase when compiled format changes
|
||||||
selfieMagic: 24, // Increase when selfie format changes
|
selfieMagic: 25, // Increase when selfie format changes
|
||||||
},
|
},
|
||||||
|
|
||||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/759#issuecomment-546654501
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/759#issuecomment-546654501
|
||||||
|
@ -710,12 +710,7 @@ HNTrieContainer.prototype.HNTrieRef.prototype.needle = '';
|
|||||||
|
|
||||||
// Soft-dependency on vAPI so that the code here can be used outside of
|
// Soft-dependency on vAPI so that the code here can be used outside of
|
||||||
// uBO (i.e. tests, benchmarks)
|
// uBO (i.e. tests, benchmarks)
|
||||||
if (
|
if ( typeof vAPI === 'object' && vAPI.canWASM !== true ) { return; }
|
||||||
typeof vAPI === 'object' &&
|
|
||||||
vAPI.webextFlavor.soup.has('firefox') === false
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Soft-dependency on µBlock's advanced settings so that the code here can
|
// Soft-dependency on µBlock's advanced settings so that the code here can
|
||||||
// be used outside of uBO (i.e. tests, benchmarks)
|
// be used outside of uBO (i.e. tests, benchmarks)
|
||||||
|
@ -1518,26 +1518,25 @@ const FilterDataHolderResult = class {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const FilterCollection = class {
|
const FilterCollection = class {
|
||||||
constructor(i = 0, n = 0) {
|
constructor(i = 0) {
|
||||||
this.i = i | 0;
|
this.i = i | 0;
|
||||||
this.n = n | 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get size() {
|
get size() {
|
||||||
return this.n;
|
let n = 0;
|
||||||
|
this.forEach(( ) => { n += 1; });
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
unshift(iunit) {
|
unshift(iunit) {
|
||||||
const j = this.i;
|
const j = this.i;
|
||||||
this.i = filterSequenceAdd(iunit, j);
|
this.i = filterSequenceAdd(iunit, j);
|
||||||
this.n += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shift() {
|
shift() {
|
||||||
const sequences = filterSequences;
|
const sequences = filterSequences;
|
||||||
filterUnits[sequences[this.i+0]] = null;
|
filterUnits[sequences[this.i+0]] = null;
|
||||||
this.i = sequences[this.i+1];
|
this.i = sequences[this.i+1];
|
||||||
this.n -= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
forEach(fn) {
|
forEach(fn) {
|
||||||
@ -1553,7 +1552,7 @@ const FilterCollection = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toSelfie() {
|
toSelfie() {
|
||||||
return [ this.fid, this.i, this.n ];
|
return [ this.fid, this.i ];
|
||||||
}
|
}
|
||||||
|
|
||||||
static compile(ctor, fdata) {
|
static compile(ctor, fdata) {
|
||||||
@ -1577,7 +1576,7 @@ const FilterCollection = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static fromSelfie(ctor, args) {
|
static fromSelfie(ctor, args) {
|
||||||
return new ctor(args[1], args[2]);
|
return new ctor(args[1]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1585,14 +1584,13 @@ const FilterCollection = class {
|
|||||||
|
|
||||||
const FilterComposite = class extends FilterCollection {
|
const FilterComposite = class extends FilterCollection {
|
||||||
match() {
|
match() {
|
||||||
let i = this.i;
|
|
||||||
if ( i === 0 ) { return false; }
|
|
||||||
const sequences = filterSequences;
|
const sequences = filterSequences;
|
||||||
const units = filterUnits;
|
const units = filterUnits;
|
||||||
do {
|
let i = this.i;
|
||||||
|
while ( i !== 0 ) {
|
||||||
if ( units[sequences[i+0]].match() !== true ) { return false; }
|
if ( units[sequences[i+0]].match() !== true ) { return false; }
|
||||||
i = sequences[i+1];
|
i = sequences[i+1];
|
||||||
} while ( i !== 0 );
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1868,18 +1866,17 @@ const FilterBucket = class extends FilterCollection {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let i = this.i;
|
|
||||||
if ( i === 0 ) { return false; }
|
|
||||||
const sequences = filterSequences;
|
const sequences = filterSequences;
|
||||||
const units = filterUnits;
|
const units = filterUnits;
|
||||||
do {
|
let i = this.i;
|
||||||
|
while ( i !== 0 ) {
|
||||||
if ( units[sequences[i+0]].match() ) {
|
if ( units[sequences[i+0]].match() ) {
|
||||||
this.$matchedTrie = false;
|
this.$matchedTrie = false;
|
||||||
this.$matchedUnit = sequences[i+0];
|
this.$matchedUnit = sequences[i+0];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
i = sequences[i+1];
|
i = sequences[i+1];
|
||||||
} while ( i !== 0 );
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1910,19 +1907,14 @@ const FilterBucket = class extends FilterCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
optimize() {
|
optimize() {
|
||||||
if ( this.n < 3 ) { return; }
|
|
||||||
const units = filterUnits;
|
const units = filterUnits;
|
||||||
const trieables = new Set();
|
let n = 0;
|
||||||
let i = this.i;
|
let i = this.i;
|
||||||
for (;;) {
|
do {
|
||||||
const f = units[filterSequences[i+0]];
|
if ( units[filterSequences[i+0]].isBidiTrieable ) { n += 1; }
|
||||||
if ( f.isBidiTrieable === true ) {
|
|
||||||
trieables.add(i);
|
|
||||||
}
|
|
||||||
i = filterSequences[i+1];
|
i = filterSequences[i+1];
|
||||||
if ( i === 0 ) { break; }
|
} while ( i !== 0 && n < 3 );
|
||||||
}
|
if ( n < 3 ) { return; }
|
||||||
if ( trieables.size < 3 ) { return; }
|
|
||||||
if ( this.plainTrie === null ) {
|
if ( this.plainTrie === null ) {
|
||||||
this.plainTrie = bidiTrie.createOne();
|
this.plainTrie = bidiTrie.createOne();
|
||||||
}
|
}
|
||||||
@ -1931,7 +1923,7 @@ const FilterBucket = class extends FilterCollection {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
const iunit = filterSequences[i+0];
|
const iunit = filterSequences[i+0];
|
||||||
const inext = filterSequences[i+1];
|
const inext = filterSequences[i+1];
|
||||||
if ( trieables.has(i) ) {
|
if ( units[iunit].isBidiTrieable ) {
|
||||||
this._addToTrie(iunit);
|
this._addToTrie(iunit);
|
||||||
if ( iprev !== 0 ) {
|
if ( iprev !== 0 ) {
|
||||||
filterSequences[iprev+1] = inext;
|
filterSequences[iprev+1] = inext;
|
||||||
@ -1982,8 +1974,8 @@ const FilterBucket = class extends FilterCollection {
|
|||||||
|
|
||||||
static fromSelfie(args) {
|
static fromSelfie(args) {
|
||||||
const bucket = FilterCollection.fromSelfie(FilterBucket, args);
|
const bucket = FilterCollection.fromSelfie(FilterBucket, args);
|
||||||
if ( args.length > 3 && Array.isArray(args[3]) ) {
|
if ( args.length > 2 && Array.isArray(args[2]) ) {
|
||||||
bucket.plainTrie = bidiTrie.createOne(args[3]);
|
bucket.plainTrie = bidiTrie.createOne(args[2]);
|
||||||
}
|
}
|
||||||
return bucket;
|
return bucket;
|
||||||
}
|
}
|
||||||
@ -2688,6 +2680,8 @@ FilterContainer.prototype.freeze = function() {
|
|||||||
const unserialize = µb.CompiledLineIO.unserialize;
|
const unserialize = µb.CompiledLineIO.unserialize;
|
||||||
const units = filterUnits;
|
const units = filterUnits;
|
||||||
|
|
||||||
|
const t0 = Date.now();
|
||||||
|
|
||||||
for ( const line of this.goodFilters ) {
|
for ( const line of this.goodFilters ) {
|
||||||
if ( this.badFilters.has(line) ) {
|
if ( this.badFilters.has(line) ) {
|
||||||
this.discardedCount += 1;
|
this.discardedCount += 1;
|
||||||
@ -2791,6 +2785,8 @@ FilterContainer.prototype.freeze = function() {
|
|||||||
FilterHostnameDict.optimize();
|
FilterHostnameDict.optimize();
|
||||||
bidiTrieOptimize();
|
bidiTrieOptimize();
|
||||||
this.frozen = true;
|
this.frozen = true;
|
||||||
|
|
||||||
|
log.info(`staticNetFilteringEngine.freeze() took ${Date.now()-t0} ms`);
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -621,7 +621,11 @@
|
|||||||
const loadedListKeys = [];
|
const loadedListKeys = [];
|
||||||
let loadingPromise;
|
let loadingPromise;
|
||||||
|
|
||||||
|
const t0 = Date.now();
|
||||||
|
|
||||||
const onDone = function() {
|
const onDone = function() {
|
||||||
|
log.info(`loadFilterLists() took ${Date.now()-t0} ms`);
|
||||||
|
|
||||||
this.staticNetFilteringEngine.freeze();
|
this.staticNetFilteringEngine.freeze();
|
||||||
this.staticExtFilteringEngine.freeze();
|
this.staticExtFilteringEngine.freeze();
|
||||||
this.redirectEngine.freeze();
|
this.redirectEngine.freeze();
|
||||||
@ -696,9 +700,9 @@
|
|||||||
if ( loadingPromise instanceof Promise === false ) {
|
if ( loadingPromise instanceof Promise === false ) {
|
||||||
loadedListKeys.length = 0;
|
loadedListKeys.length = 0;
|
||||||
loadingPromise = Promise.all([
|
loadingPromise = Promise.all([
|
||||||
this.getAvailableLists().then(lists => {
|
this.getAvailableLists().then(lists =>
|
||||||
return onFilterListsReady.call(this, lists);
|
onFilterListsReady.call(this, lists)
|
||||||
}),
|
),
|
||||||
this.loadRedirectResources(),
|
this.loadRedirectResources(),
|
||||||
]).then(( ) => {
|
]).then(( ) => {
|
||||||
onDone.call(this);
|
onDone.call(this);
|
||||||
|
103
src/js/strie.js
103
src/js/strie.js
@ -174,40 +174,40 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
|
|||||||
const buf8 = this.buf8;
|
const buf8 = this.buf8;
|
||||||
const char0 = buf32[CHAR0_SLOT];
|
const char0 = buf32[CHAR0_SLOT];
|
||||||
const aR = buf32[HAYSTACK_SIZE_SLOT];
|
const aR = buf32[HAYSTACK_SIZE_SLOT];
|
||||||
let al = ai;
|
let al = ai, x = 0, y = 0;
|
||||||
let c, v, bl, n;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
c = buf8[al];
|
x = buf8[al];
|
||||||
al += 1;
|
al += 1;
|
||||||
// find first segment with a first-character match
|
// find matching segment
|
||||||
for (;;) {
|
for (;;) {
|
||||||
v = buf32[icell+SEGMENT_INFO];
|
y = buf32[icell+SEGMENT_INFO];
|
||||||
bl = char0 + (v & 0x00FFFFFF);
|
let bl = char0 + (y & 0x00FFFFFF);
|
||||||
if ( buf8[bl] === c ) { break; }
|
if ( buf8[bl] === x ) {
|
||||||
|
y = (y >>> 24) - 1;
|
||||||
|
if ( y !== 0 ) {
|
||||||
|
x = al + y;
|
||||||
|
if ( x > aR ) { return 0; }
|
||||||
|
for (;;) {
|
||||||
|
bl += 1;
|
||||||
|
if ( buf8[bl] !== buf8[al] ) { return 0; }
|
||||||
|
al += 1;
|
||||||
|
if ( al === x ) { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
icell = buf32[icell+CELL_OR];
|
icell = buf32[icell+CELL_OR];
|
||||||
if ( icell === 0 ) { return 0; }
|
if ( icell === 0 ) { return 0; }
|
||||||
}
|
}
|
||||||
// all characters in segment must match
|
|
||||||
n = (v >>> 24) - 1;
|
|
||||||
if ( n !== 0 ) {
|
|
||||||
const ar = al + n;
|
|
||||||
if ( ar > aR ) { return 0; }
|
|
||||||
let i = al, j = bl + 1;
|
|
||||||
do {
|
|
||||||
if ( buf8[i] !== buf8[j] ) { return 0; }
|
|
||||||
j += 1; i += 1;
|
|
||||||
} while ( i !== ar );
|
|
||||||
al = i;
|
|
||||||
}
|
|
||||||
// next segment
|
// next segment
|
||||||
icell = buf32[icell+CELL_AND];
|
icell = buf32[icell+CELL_AND];
|
||||||
v = buf32[icell+BCELL_EXTRA];
|
x = buf32[icell+BCELL_EXTRA];
|
||||||
if ( v <= BCELL_EXTRA_MAX ) {
|
if ( x <= BCELL_EXTRA_MAX ) {
|
||||||
if ( v !== 0 && this.matchesExtra(ai, al, v) !== 0 ) {
|
if ( x !== 0 && this.matchesExtra(ai, al, x) !== 0 ) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
let inext = buf32[icell+BCELL_ALT_AND];
|
x = buf32[icell+BCELL_ALT_AND];
|
||||||
if ( inext !== 0 && this.matchesLeft(inext, ai, al) !== 0 ) {
|
if ( x !== 0 && this.matchesLeft(x, ai, al) !== 0 ) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
icell = buf32[icell+BCELL_NEXT_AND];
|
icell = buf32[icell+BCELL_NEXT_AND];
|
||||||
@ -218,41 +218,41 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
matchesLeft(iroot, ar, r) {
|
matchesLeft(icell, ar, r) {
|
||||||
const buf32 = this.buf32;
|
const buf32 = this.buf32;
|
||||||
const buf8 = this.buf8;
|
const buf8 = this.buf8;
|
||||||
const char0 = buf32[CHAR0_SLOT];
|
const char0 = buf32[CHAR0_SLOT];
|
||||||
let icell = iroot;
|
let x = 0, y = 0;
|
||||||
let c, v, br, n;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ( ar === 0 ) { return 0; }
|
if ( ar === 0 ) { return 0; }
|
||||||
ar -= 1;
|
ar -= 1;
|
||||||
c = buf8[ar];
|
x = buf8[ar];
|
||||||
// find first segment with a first-character match
|
// find first segment with a first-character match
|
||||||
for (;;) {
|
for (;;) {
|
||||||
v = buf32[icell+SEGMENT_INFO];
|
y = buf32[icell+SEGMENT_INFO];
|
||||||
n = (v >>> 24) - 1;
|
let br = char0 + (y & 0x00FFFFFF);
|
||||||
br = char0 + (v & 0x00FFFFFF) + n;
|
y = (y >>> 24) - 1;
|
||||||
if ( buf8[br] === c ) { break; }
|
br += y;
|
||||||
|
if ( buf8[br] === x ) { // all characters in segment must match
|
||||||
|
if ( y !== 0 ) {
|
||||||
|
x = ar - y;
|
||||||
|
if ( x < 0 ) { return 0; }
|
||||||
|
for (;;) {
|
||||||
|
ar -= 1; br -= 1;
|
||||||
|
if ( buf8[ar] !== buf8[br] ) { return 0; }
|
||||||
|
if ( ar === x ) { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
icell = buf32[icell+CELL_OR];
|
icell = buf32[icell+CELL_OR];
|
||||||
if ( icell === 0 ) { return 0; }
|
if ( icell === 0 ) { return 0; }
|
||||||
}
|
}
|
||||||
// all characters in segment must match
|
|
||||||
if ( n !== 0 ) {
|
|
||||||
const al = ar - n;
|
|
||||||
if ( al < 0 ) { return 0; }
|
|
||||||
let i = ar, j = br;
|
|
||||||
do {
|
|
||||||
i -= 1; j -= 1;
|
|
||||||
if ( buf8[i] !== buf8[j] ) { return 0; }
|
|
||||||
} while ( i !== al );
|
|
||||||
ar = i;
|
|
||||||
}
|
|
||||||
// next segment
|
// next segment
|
||||||
icell = buf32[icell+CELL_AND];
|
icell = buf32[icell+CELL_AND];
|
||||||
v = buf32[icell+BCELL_EXTRA];
|
x = buf32[icell+BCELL_EXTRA];
|
||||||
if ( v <= BCELL_EXTRA_MAX ) {
|
if ( x <= BCELL_EXTRA_MAX ) {
|
||||||
if ( v !== 0 && this.matchesExtra(ar, r, v) !== 0 ) {
|
if ( x !== 0 && this.matchesExtra(ar, r, x) !== 0 ) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
icell = buf32[icell+BCELL_NEXT_AND];
|
icell = buf32[icell+BCELL_NEXT_AND];
|
||||||
@ -263,16 +263,16 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
|
|||||||
}
|
}
|
||||||
|
|
||||||
matchesExtra(l, r, ix) {
|
matchesExtra(l, r, ix) {
|
||||||
let iu;
|
let iu = 0;
|
||||||
if ( ix !== 1 ) {
|
if ( ix !== 1 ) {
|
||||||
iu = this.extraHandler(l, r, ix);
|
iu = this.extraHandler(l, r, ix);
|
||||||
if ( iu === 0 ) { return 0; }
|
if ( iu === 0 ) { return 0; }
|
||||||
} else {
|
} else {
|
||||||
iu = -1;
|
iu = -1;
|
||||||
}
|
}
|
||||||
|
this.buf32[RESULT_IU_SLOT] = iu;
|
||||||
this.buf32[RESULT_L_SLOT] = l;
|
this.buf32[RESULT_L_SLOT] = l;
|
||||||
this.buf32[RESULT_R_SLOT] = r;
|
this.buf32[RESULT_R_SLOT] = r;
|
||||||
this.buf32[RESULT_IU_SLOT] = iu;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -926,12 +926,7 @@ const getWasmModule = (( ) => {
|
|||||||
|
|
||||||
// Soft-dependency on vAPI so that the code here can be used outside of
|
// Soft-dependency on vAPI so that the code here can be used outside of
|
||||||
// uBO (i.e. tests, benchmarks)
|
// uBO (i.e. tests, benchmarks)
|
||||||
if (
|
if ( typeof vAPI === 'object' && vAPI.canWASM !== true ) { return; }
|
||||||
typeof vAPI === 'object' &&
|
|
||||||
vAPI.webextFlavor.soup.has('firefox') === false
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The wasm module will work only if CPU is natively little-endian,
|
// The wasm module will work only if CPU is natively little-endian,
|
||||||
// as we use native uint32 array in our js code.
|
// as we use native uint32 array in our js code.
|
||||||
|
@ -149,7 +149,7 @@
|
|||||||
_tokenize(encodeInto) {
|
_tokenize(encodeInto) {
|
||||||
const tokens = this._tokens;
|
const tokens = this._tokens;
|
||||||
let url = this._urlOut;
|
let url = this._urlOut;
|
||||||
let l = url.length;
|
let l = url.length | 0;
|
||||||
if ( l === 0 ) { return 0; }
|
if ( l === 0 ) { return 0; }
|
||||||
if ( l > 2048 ) {
|
if ( l > 2048 ) {
|
||||||
url = url.slice(0, 2048);
|
url = url.slice(0, 2048);
|
||||||
@ -163,7 +163,7 @@
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ( i === l ) { return j; }
|
if ( i === l ) { return j; }
|
||||||
c = url.charCodeAt(i);
|
c = url.charCodeAt(i) | 0;
|
||||||
charCodes[i] = c;
|
charCodes[i] = c;
|
||||||
v = vtc[c];
|
v = vtc[c];
|
||||||
i += 1;
|
i += 1;
|
||||||
@ -172,7 +172,7 @@
|
|||||||
th = v; ti = i - 1; n = 1;
|
th = v; ti = i - 1; n = 1;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ( i === l ) { break; }
|
if ( i === l ) { break; }
|
||||||
c = url.charCodeAt(i);
|
c = url.charCodeAt(i) | 0;
|
||||||
charCodes[i] = c;
|
charCodes[i] = c;
|
||||||
v = vtc[c];
|
v = vtc[c];
|
||||||
i += 1;
|
i += 1;
|
||||||
|
Binary file not shown.
@ -60,14 +60,9 @@
|
|||||||
(local $char0 i32)
|
(local $char0 i32)
|
||||||
(local $aR i32)
|
(local $aR i32)
|
||||||
(local $al i32)
|
(local $al i32)
|
||||||
(local $c i32)
|
|
||||||
(local $v i32)
|
|
||||||
(local $bl i32)
|
(local $bl i32)
|
||||||
(local $n i32)
|
(local $x i32)
|
||||||
(local $ar i32)
|
(local $y i32)
|
||||||
(local $i i32)
|
|
||||||
(local $j i32)
|
|
||||||
(local $inext i32)
|
|
||||||
;; trie index is a uint32 offset, need to convert to uint8 offset
|
;; trie index is a uint32 offset, need to convert to uint8 offset
|
||||||
get_local $icell
|
get_local $icell
|
||||||
i32.const 2
|
i32.const 2
|
||||||
@ -90,33 +85,78 @@
|
|||||||
block $matchNotFound
|
block $matchNotFound
|
||||||
;; for (;;) {
|
;; for (;;) {
|
||||||
loop $mainLoop
|
loop $mainLoop
|
||||||
;; c = buf8[al];
|
;; x = buf8[al];
|
||||||
get_local $al
|
get_local $al
|
||||||
i32.load8_u
|
i32.load8_u
|
||||||
set_local $c
|
set_local $x
|
||||||
;; al += 1;
|
;; al += 1;
|
||||||
get_local $al
|
get_local $al
|
||||||
i32.const 1
|
i32.const 1
|
||||||
i32.add
|
i32.add
|
||||||
set_local $al
|
set_local $al
|
||||||
;; // find first segment with a first-character match
|
;; // find matching segment
|
||||||
;; for (;;) {
|
;; for (;;) {
|
||||||
block $breakMatchFirstChar loop $matchFirstChar
|
block $nextSegment loop $findSegment
|
||||||
;; v = buf32[icell+SEGMENT_INFO];
|
;; y = buf32[icell+SEGMENT_INFO];
|
||||||
get_local $icell
|
get_local $icell
|
||||||
i32.load offset=8 align=4
|
i32.load offset=8 align=4
|
||||||
tee_local $v
|
tee_local $y
|
||||||
;; bl = char0 + (v & 0x00FFFFFF);
|
;; bl = char0 + (y & 0x00FFFFFF);
|
||||||
i32.const 0x00FFFFFF
|
i32.const 0x00FFFFFF
|
||||||
i32.and
|
i32.and
|
||||||
get_local $char0
|
get_local $char0
|
||||||
i32.add
|
i32.add
|
||||||
tee_local $bl
|
tee_local $bl
|
||||||
;; if ( buf8[bl] === c ) { break; }
|
;; if ( buf8[bl] === x ) {
|
||||||
i32.load8_u
|
i32.load8_u
|
||||||
get_local $c
|
get_local $x
|
||||||
i32.eq
|
i32.eq
|
||||||
br_if $breakMatchFirstChar
|
if
|
||||||
|
;; y = (y >>> 24) - 1;
|
||||||
|
get_local $y
|
||||||
|
i32.const 24
|
||||||
|
i32.shr_u
|
||||||
|
i32.const 1
|
||||||
|
i32.sub
|
||||||
|
tee_local $y
|
||||||
|
;; if ( n !== 0 ) {
|
||||||
|
if
|
||||||
|
;; x = al + y;
|
||||||
|
get_local $y
|
||||||
|
get_local $al
|
||||||
|
i32.add
|
||||||
|
tee_local $x
|
||||||
|
;; if ( x > aR ) { return 0; }
|
||||||
|
get_local $aR
|
||||||
|
i32.gt_u
|
||||||
|
br_if $matchNotFound
|
||||||
|
;; for (;;) {
|
||||||
|
loop
|
||||||
|
;; bl += 1;
|
||||||
|
get_local $bl
|
||||||
|
i32.const 1
|
||||||
|
i32.add
|
||||||
|
tee_local $bl
|
||||||
|
;; if ( buf8[bl] !== buf8[al] ) { return 0; }
|
||||||
|
i32.load8_u
|
||||||
|
get_local $al
|
||||||
|
i32.load8_u
|
||||||
|
i32.ne
|
||||||
|
br_if $matchNotFound
|
||||||
|
;; al += 1;
|
||||||
|
get_local $al
|
||||||
|
i32.const 1
|
||||||
|
i32.add
|
||||||
|
tee_local $al
|
||||||
|
;; if ( al === x ) { break; }
|
||||||
|
get_local $x
|
||||||
|
i32.ne
|
||||||
|
br_if 0
|
||||||
|
end
|
||||||
|
;; }
|
||||||
|
end
|
||||||
|
br $nextSegment
|
||||||
|
end
|
||||||
;; icell = buf32[icell+CELL_OR];
|
;; icell = buf32[icell+CELL_OR];
|
||||||
get_local $icell
|
get_local $icell
|
||||||
i32.load offset=4 align=4
|
i32.load offset=4 align=4
|
||||||
@ -126,63 +166,9 @@
|
|||||||
;; if ( icell === 0 ) { return 0; }
|
;; if ( icell === 0 ) { return 0; }
|
||||||
i32.eqz
|
i32.eqz
|
||||||
br_if $matchNotFound
|
br_if $matchNotFound
|
||||||
br $matchFirstChar
|
br $findSegment
|
||||||
;; }
|
;; }
|
||||||
end end
|
end end
|
||||||
;; // all characters in segment must match
|
|
||||||
;; n = (v >>> 24) - 1;
|
|
||||||
get_local $v
|
|
||||||
i32.const 24
|
|
||||||
i32.shr_u
|
|
||||||
i32.const 1
|
|
||||||
i32.sub
|
|
||||||
tee_local $n
|
|
||||||
;; if ( n !== 0 ) {
|
|
||||||
if
|
|
||||||
;; const ar = al + n;
|
|
||||||
get_local $n
|
|
||||||
get_local $al
|
|
||||||
i32.add
|
|
||||||
tee_local $ar
|
|
||||||
;; if ( ar > aR ) { return 0; }
|
|
||||||
get_local $aR
|
|
||||||
i32.gt_u
|
|
||||||
br_if $matchNotFound
|
|
||||||
;; let i = al, j = bl + 1;
|
|
||||||
get_local $al
|
|
||||||
set_local $i
|
|
||||||
get_local $bl
|
|
||||||
i32.const 1
|
|
||||||
i32.add
|
|
||||||
set_local $j
|
|
||||||
;; do {
|
|
||||||
loop
|
|
||||||
;; if ( buf8[i] !== buf8[j] ) { return 0; }
|
|
||||||
get_local $i
|
|
||||||
i32.load8_u
|
|
||||||
get_local $j
|
|
||||||
i32.load8_u
|
|
||||||
i32.ne
|
|
||||||
br_if $matchNotFound
|
|
||||||
;; j += 1; i += 1;
|
|
||||||
get_local $j
|
|
||||||
i32.const 1
|
|
||||||
i32.add
|
|
||||||
set_local $j
|
|
||||||
get_local $i
|
|
||||||
i32.const 1
|
|
||||||
i32.add
|
|
||||||
tee_local $i
|
|
||||||
;; } while ( i !== ar );
|
|
||||||
get_local $ar
|
|
||||||
i32.ne
|
|
||||||
br_if 0
|
|
||||||
end
|
|
||||||
;; al = i;
|
|
||||||
get_local $i
|
|
||||||
set_local $al
|
|
||||||
;; }
|
|
||||||
end
|
|
||||||
;; // next segment
|
;; // next segment
|
||||||
;; icell = buf32[icell+CELL_AND];
|
;; icell = buf32[icell+CELL_AND];
|
||||||
get_local $icell
|
get_local $icell
|
||||||
@ -190,33 +176,33 @@
|
|||||||
i32.const 2
|
i32.const 2
|
||||||
i32.shl
|
i32.shl
|
||||||
tee_local $icell
|
tee_local $icell
|
||||||
;; const v = buf32[icell+BCELL_EXTRA];
|
;; const x = buf32[icell+BCELL_EXTRA];
|
||||||
i32.load offset=8 align=4
|
i32.load offset=8 align=4
|
||||||
tee_local $v
|
tee_local $x
|
||||||
;; if ( v <= BCELL_EXTRA_MAX ) {
|
;; if ( x <= BCELL_EXTRA_MAX ) {
|
||||||
i32.const 0x00FFFFFF
|
i32.const 0x00FFFFFF
|
||||||
i32.le_u
|
i32.le_u
|
||||||
if
|
if
|
||||||
;; if ( v !== 0 && this.matchesExtra(ai, al, v) !== 0 ) {
|
;; if ( x !== 0 && this.matchesExtra(ai, al, x) !== 0 ) {
|
||||||
;; return 1;
|
;; return 1;
|
||||||
;; }
|
;; }
|
||||||
get_local $v
|
get_local $x
|
||||||
if
|
if
|
||||||
get_local $ai
|
get_local $ai
|
||||||
get_local $al
|
get_local $al
|
||||||
get_local $v
|
get_local $x
|
||||||
call $matchesExtra
|
call $matchesExtra
|
||||||
br_if $matchFound
|
br_if $matchFound
|
||||||
end
|
end
|
||||||
;; let inext = buf32[icell+BCELL_ALT_AND];
|
;; x = buf32[icell+BCELL_ALT_AND];
|
||||||
get_local $icell
|
get_local $icell
|
||||||
i32.load offset=4 align=4
|
i32.load offset=4 align=4
|
||||||
i32.const 2
|
i32.const 2
|
||||||
i32.shl
|
i32.shl
|
||||||
tee_local $inext
|
tee_local $x
|
||||||
;; if ( inext !== 0 && this.matchesLeft(inext, ai, al) !== 0 ) {
|
;; if ( x !== 0 && this.matchesLeft(x, ai, al) !== 0 ) {
|
||||||
if
|
if
|
||||||
get_local $inext
|
get_local $x
|
||||||
get_local $ai
|
get_local $ai
|
||||||
get_local $al
|
get_local $al
|
||||||
call $matchesLeft
|
call $matchesLeft
|
||||||
@ -260,14 +246,10 @@
|
|||||||
(param $r i32) ;; right bound of match so far
|
(param $r i32) ;; right bound of match so far
|
||||||
(result i32) ;; result: 0 = no match, 1 = match
|
(result i32) ;; result: 0 = no match, 1 = match
|
||||||
(local $char0 i32)
|
(local $char0 i32)
|
||||||
(local $c i32)
|
|
||||||
(local $v i32)
|
|
||||||
(local $bl i32)
|
(local $bl i32)
|
||||||
(local $n i32)
|
|
||||||
(local $al i32)
|
|
||||||
(local $br i32)
|
(local $br i32)
|
||||||
(local $i i32)
|
(local $x i32)
|
||||||
(local $j i32)
|
(local $y i32)
|
||||||
;; const buf32 = this.buf32;
|
;; const buf32 = this.buf32;
|
||||||
;; const buf8 = this.buf8;
|
;; const buf8 = this.buf8;
|
||||||
;; const char0 = buf32[CHAR0_SLOT];
|
;; const char0 = buf32[CHAR0_SLOT];
|
||||||
@ -287,35 +269,76 @@
|
|||||||
i32.const 1
|
i32.const 1
|
||||||
i32.sub
|
i32.sub
|
||||||
tee_local $ar
|
tee_local $ar
|
||||||
;; c = buf8[ar];
|
;; x = buf8[ar];
|
||||||
i32.load8_u
|
i32.load8_u
|
||||||
set_local $c
|
set_local $x
|
||||||
;; // find first segment with a first-character match
|
;; // find matching segment
|
||||||
;; for (;;) {
|
;; for (;;) {
|
||||||
block $breakMatchFirstChar loop $matchFirstChar
|
block $nextSegment loop $findSegment
|
||||||
;; v = buf32[icell+SEGMENT_INFO];
|
;; y = buf32[icell+SEGMENT_INFO];
|
||||||
get_local $icell
|
get_local $icell
|
||||||
i32.load offset=8 align=4
|
i32.load offset=8 align=4
|
||||||
tee_local $v
|
tee_local $y
|
||||||
;; n = (v >>> 24) - 1;
|
;; br = char0 + (y & 0x00FFFFFF);
|
||||||
|
i32.const 0x00FFFFFF
|
||||||
|
i32.and
|
||||||
|
get_local $char0
|
||||||
|
i32.add
|
||||||
|
tee_local $br
|
||||||
|
;; y = (y >>> 24) - 1;
|
||||||
|
get_local $y
|
||||||
i32.const 24
|
i32.const 24
|
||||||
i32.shr_u
|
i32.shr_u
|
||||||
i32.const 1
|
i32.const 1
|
||||||
i32.sub
|
i32.sub
|
||||||
tee_local $n
|
tee_local $y
|
||||||
;; br = char0 + (v & 0x00FFFFFF) + n;
|
;; br += y;
|
||||||
get_local $char0
|
|
||||||
i32.add
|
|
||||||
get_local $v
|
|
||||||
i32.const 0x00FFFFFF
|
|
||||||
i32.and
|
|
||||||
i32.add
|
i32.add
|
||||||
tee_local $br
|
tee_local $br
|
||||||
;; if ( buf8[br] === c ) { break; }
|
;; if ( buf8[br] === x ) {
|
||||||
i32.load8_u
|
i32.load8_u
|
||||||
get_local $c
|
get_local $x
|
||||||
i32.eq
|
i32.eq
|
||||||
br_if $breakMatchFirstChar
|
if
|
||||||
|
;; // all characters in segment must match
|
||||||
|
;; if ( y !== 0 ) {
|
||||||
|
get_local $y
|
||||||
|
if
|
||||||
|
;; x = ar - y;
|
||||||
|
get_local $ar
|
||||||
|
get_local $y
|
||||||
|
i32.sub
|
||||||
|
tee_local $x
|
||||||
|
;; if ( x < 0 ) { return 0; }
|
||||||
|
i32.const 0
|
||||||
|
i32.lt_s
|
||||||
|
br_if $matchNotFound
|
||||||
|
;; for (;;) {
|
||||||
|
loop
|
||||||
|
;; ar -= 1; br -= 1;
|
||||||
|
;; if ( buf8[ar] !== buf8[br] ) { return 0; }
|
||||||
|
get_local $ar
|
||||||
|
i32.const 1
|
||||||
|
i32.sub
|
||||||
|
tee_local $ar
|
||||||
|
i32.load8_u
|
||||||
|
get_local $br
|
||||||
|
i32.const 1
|
||||||
|
i32.sub
|
||||||
|
tee_local $br
|
||||||
|
i32.load8_u
|
||||||
|
i32.ne
|
||||||
|
br_if $matchNotFound
|
||||||
|
;; if ( ar === x ) { break; }
|
||||||
|
get_local $ar
|
||||||
|
get_local $x
|
||||||
|
i32.ne
|
||||||
|
br_if 0
|
||||||
|
end
|
||||||
|
;; }
|
||||||
|
end
|
||||||
|
br $nextSegment
|
||||||
|
end
|
||||||
;; icell = buf32[icell+CELL_OR];
|
;; icell = buf32[icell+CELL_OR];
|
||||||
get_local $icell
|
get_local $icell
|
||||||
i32.load offset=4 align=4
|
i32.load offset=4 align=4
|
||||||
@ -325,54 +348,9 @@
|
|||||||
;; if ( icell === 0 ) { return 0; }
|
;; if ( icell === 0 ) { return 0; }
|
||||||
i32.eqz
|
i32.eqz
|
||||||
br_if $matchNotFound
|
br_if $matchNotFound
|
||||||
br $matchFirstChar
|
br $findSegment
|
||||||
;; }
|
;; }
|
||||||
end end
|
end end
|
||||||
;; // all characters in segment must match
|
|
||||||
;; if ( n !== 0 ) {
|
|
||||||
get_local $n
|
|
||||||
if
|
|
||||||
;; const al = ar - n;
|
|
||||||
get_local $ar
|
|
||||||
get_local $n
|
|
||||||
i32.sub
|
|
||||||
tee_local $al
|
|
||||||
;; if ( al < 0 ) { return 0; }
|
|
||||||
i32.const 0
|
|
||||||
i32.lt_s
|
|
||||||
br_if $matchNotFound
|
|
||||||
;; let i = ar, j = br;
|
|
||||||
get_local $ar
|
|
||||||
set_local $i
|
|
||||||
get_local $br
|
|
||||||
set_local $j
|
|
||||||
;; do {
|
|
||||||
loop
|
|
||||||
;; i -= 1; j -= 1;
|
|
||||||
;; if ( buf8[i] !== buf8[j] ) { return 0; }
|
|
||||||
get_local $i
|
|
||||||
i32.const 1
|
|
||||||
i32.sub
|
|
||||||
tee_local $i
|
|
||||||
i32.load8_u
|
|
||||||
get_local $j
|
|
||||||
i32.const 1
|
|
||||||
i32.sub
|
|
||||||
tee_local $j
|
|
||||||
i32.load8_u
|
|
||||||
i32.ne
|
|
||||||
br_if $matchNotFound
|
|
||||||
;; } while ( i !== al );
|
|
||||||
get_local $i
|
|
||||||
get_local $al
|
|
||||||
i32.ne
|
|
||||||
br_if 0
|
|
||||||
end
|
|
||||||
;; ar = i;
|
|
||||||
get_local $i
|
|
||||||
set_local $ar
|
|
||||||
;; }
|
|
||||||
end
|
|
||||||
;; // next segment
|
;; // next segment
|
||||||
;; icell = buf32[icell+CELL_AND];
|
;; icell = buf32[icell+CELL_AND];
|
||||||
get_local $icell
|
get_local $icell
|
||||||
@ -380,21 +358,21 @@
|
|||||||
i32.const 2
|
i32.const 2
|
||||||
i32.shl
|
i32.shl
|
||||||
tee_local $icell
|
tee_local $icell
|
||||||
;; const v = buf32[icell+BCELL_EXTRA];
|
;; const x = buf32[icell+BCELL_EXTRA];
|
||||||
i32.load offset=8 align=4
|
i32.load offset=8 align=4
|
||||||
tee_local $v
|
tee_local $x
|
||||||
;; if ( v <= BCELL_EXTRA_MAX ) {
|
;; if ( x <= BCELL_EXTRA_MAX ) {
|
||||||
i32.const 0x00FFFFFF
|
i32.const 0x00FFFFFF
|
||||||
i32.le_u
|
i32.le_u
|
||||||
if
|
if
|
||||||
;; if ( v !== 0 && this.matchesExtra(ar, r, v) !== 0 ) {
|
;; if ( x !== 0 && this.matchesExtra(ar, r, x) !== 0 ) {
|
||||||
;; return 1;
|
;; return 1;
|
||||||
;; }
|
;; }
|
||||||
get_local $v
|
get_local $x
|
||||||
if
|
if
|
||||||
get_local $ar
|
get_local $ar
|
||||||
get_local $r
|
get_local $r
|
||||||
get_local $v
|
get_local $x
|
||||||
call $matchesExtra
|
call $matchesExtra
|
||||||
br_if $matchFound
|
br_if $matchFound
|
||||||
end
|
end
|
||||||
@ -431,9 +409,10 @@
|
|||||||
(param $ix i32) ;; extra token
|
(param $ix i32) ;; extra token
|
||||||
(result i32) ;; result: 0 = no match, 1 = match
|
(result i32) ;; result: 0 = no match, 1 = match
|
||||||
(local $iu i32) ;; filter unit
|
(local $iu i32) ;; filter unit
|
||||||
;; let iu;
|
block $fail
|
||||||
|
block $succeed
|
||||||
;; if ( ix !== 1 ) {
|
;; if ( ix !== 1 ) {
|
||||||
;; iu = this.extraHandler(l, r, ix);
|
;; const iu = this.extraHandler(l, r, ix);
|
||||||
;; if ( iu === 0 ) { return 0; }
|
;; if ( iu === 0 ) { return 0; }
|
||||||
get_local $ix
|
get_local $ix
|
||||||
i32.const 1
|
i32.const 1
|
||||||
@ -445,10 +424,7 @@
|
|||||||
call $extraHandler
|
call $extraHandler
|
||||||
tee_local $iu
|
tee_local $iu
|
||||||
i32.eqz
|
i32.eqz
|
||||||
if
|
br_if $fail
|
||||||
i32.const 0
|
|
||||||
return
|
|
||||||
end
|
|
||||||
;; } else {
|
;; } else {
|
||||||
;; iu = -1;
|
;; iu = -1;
|
||||||
else
|
else
|
||||||
@ -456,6 +432,10 @@
|
|||||||
set_local $iu
|
set_local $iu
|
||||||
;; }
|
;; }
|
||||||
end
|
end
|
||||||
|
;; this.buf32[RESULT_IU_SLOT] = iu;
|
||||||
|
i32.const 2076
|
||||||
|
get_local $iu
|
||||||
|
i32.store align=4
|
||||||
;; this.buf32[RESULT_L_SLOT] = l;
|
;; this.buf32[RESULT_L_SLOT] = l;
|
||||||
i32.const 2068
|
i32.const 2068
|
||||||
get_local $l
|
get_local $l
|
||||||
@ -464,11 +444,11 @@
|
|||||||
i32.const 2072
|
i32.const 2072
|
||||||
get_local $r
|
get_local $r
|
||||||
i32.store align=4
|
i32.store align=4
|
||||||
;; this.buf32[RESULT_IU_SLOT] = iu;
|
end ;; $succeed
|
||||||
i32.const 2076
|
|
||||||
get_local $iu
|
|
||||||
i32.store align=4
|
|
||||||
i32.const 1
|
i32.const 1
|
||||||
|
return
|
||||||
|
end ;; $fail
|
||||||
|
i32.const 0
|
||||||
)
|
)
|
||||||
|
|
||||||
;;
|
;;
|
||||||
@ -484,6 +464,8 @@
|
|||||||
(param $needleLen i32) ;; number of characters to match
|
(param $needleLen i32) ;; number of characters to match
|
||||||
(result i32) ;; result: 0 = no match, 1 = match
|
(result i32) ;; result: 0 = no match, 1 = match
|
||||||
(local $needleRight i32)
|
(local $needleRight i32)
|
||||||
|
block $fail
|
||||||
|
block $succeed
|
||||||
;;
|
;;
|
||||||
;; if ( haystackLeft < 0 || (haystackLeft + needleLen) > haystackRight ) {
|
;; if ( haystackLeft < 0 || (haystackLeft + needleLen) > haystackRight ) {
|
||||||
;; return 0;
|
;; return 0;
|
||||||
@ -491,38 +473,32 @@
|
|||||||
get_local $haystackLeft
|
get_local $haystackLeft
|
||||||
i32.const 0
|
i32.const 0
|
||||||
i32.lt_s
|
i32.lt_s
|
||||||
if
|
br_if $fail
|
||||||
i32.const 0
|
|
||||||
return
|
|
||||||
end
|
|
||||||
get_local $haystackLeft
|
get_local $haystackLeft
|
||||||
get_local $needleLen
|
get_local $needleLen
|
||||||
i32.add
|
i32.add
|
||||||
get_local $haystackRight
|
get_local $haystackRight
|
||||||
i32.gt_u
|
i32.gt_u
|
||||||
if
|
br_if $fail
|
||||||
i32.const 0
|
|
||||||
return
|
|
||||||
end
|
|
||||||
;; const charCodes = this.buf8;
|
;; const charCodes = this.buf8;
|
||||||
;; needleLeft += this.buf32[CHAR0_SLOT];
|
;; needleLeft += this.buf32[CHAR0_SLOT];
|
||||||
get_local $needleLeft
|
get_local $needleLeft
|
||||||
i32.const 2060 ;; CHAR0_SLOT memory address
|
i32.const 2060 ;; CHAR0_SLOT memory address
|
||||||
i32.load align=4 ;; CHAR0 memory address
|
i32.load align=4 ;; CHAR0 memory address
|
||||||
i32.add ;; needle memory address
|
i32.add ;; needle memory address
|
||||||
;; const needleRight = needleLeft + needleLen;
|
|
||||||
tee_local $needleLeft
|
tee_local $needleLeft
|
||||||
|
;; const needleRight = needleLeft + needleLen;
|
||||||
get_local $needleLen
|
get_local $needleLen
|
||||||
i32.add
|
i32.add
|
||||||
set_local $needleRight
|
set_local $needleRight
|
||||||
;; while ( charCodes[haystackLeft] === charCodes[needleLeft] ) {
|
;; while ( charCodes[haystackLeft] === charCodes[needleLeft] ) {
|
||||||
block $breakCompare loop $compare
|
loop $compare
|
||||||
get_local $haystackLeft
|
get_local $haystackLeft
|
||||||
i32.load8_u
|
i32.load8_u
|
||||||
get_local $needleLeft
|
get_local $needleLeft
|
||||||
i32.load8_u
|
i32.load8_u
|
||||||
i32.ne
|
i32.ne
|
||||||
br_if $breakCompare
|
br_if $fail
|
||||||
;; needleLeft += 1;
|
;; needleLeft += 1;
|
||||||
get_local $needleLeft
|
get_local $needleLeft
|
||||||
i32.const 1
|
i32.const 1
|
||||||
@ -531,19 +507,21 @@
|
|||||||
;; if ( needleLeft === needleRight ) { return 1; }
|
;; if ( needleLeft === needleRight ) { return 1; }
|
||||||
get_local $needleRight
|
get_local $needleRight
|
||||||
i32.eq
|
i32.eq
|
||||||
if
|
br_if $succeed
|
||||||
i32.const 1
|
|
||||||
return
|
|
||||||
end
|
|
||||||
;; haystackLeft += 1;
|
;; haystackLeft += 1;
|
||||||
i32.const 1
|
i32.const 1
|
||||||
get_local $haystackLeft
|
get_local $haystackLeft
|
||||||
i32.add
|
i32.add
|
||||||
set_local $haystackLeft
|
set_local $haystackLeft
|
||||||
br $compare
|
br $compare
|
||||||
end end
|
end
|
||||||
;; }
|
;; }
|
||||||
|
;; return 1;
|
||||||
|
end ;; $succeed
|
||||||
|
i32.const 1
|
||||||
|
return
|
||||||
;; return 0;
|
;; return 0;
|
||||||
|
end ;; $fail
|
||||||
i32.const 0
|
i32.const 0
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -564,6 +542,8 @@
|
|||||||
(local $i i32)
|
(local $i i32)
|
||||||
(local $j i32)
|
(local $j i32)
|
||||||
(local $c0 i32)
|
(local $c0 i32)
|
||||||
|
block $fail
|
||||||
|
block $succeed
|
||||||
;; haystackEnd -= needleLen;
|
;; haystackEnd -= needleLen;
|
||||||
get_local $haystackEnd
|
get_local $haystackEnd
|
||||||
get_local $needleLen
|
get_local $needleLen
|
||||||
@ -572,10 +552,7 @@
|
|||||||
;; if ( haystackEnd < haystackLeft ) { return -1; }
|
;; if ( haystackEnd < haystackLeft ) { return -1; }
|
||||||
get_local $haystackLeft
|
get_local $haystackLeft
|
||||||
i32.lt_s
|
i32.lt_s
|
||||||
if
|
br_if $fail
|
||||||
i32.const -1
|
|
||||||
return
|
|
||||||
end
|
|
||||||
;; needleLeft += this.buf32[CHAR0_SLOT];
|
;; needleLeft += this.buf32[CHAR0_SLOT];
|
||||||
get_local $needleLeft
|
get_local $needleLeft
|
||||||
i32.const 2060 ;; CHAR0_SLOT memory address
|
i32.const 2060 ;; CHAR0_SLOT memory address
|
||||||
@ -588,7 +565,7 @@
|
|||||||
set_local $needleRight
|
set_local $needleRight
|
||||||
;; const charCodes = this.buf8;
|
;; const charCodes = this.buf8;
|
||||||
;; for (;;) {
|
;; for (;;) {
|
||||||
block $breakMainLoop loop $mainLoop
|
loop $mainLoop
|
||||||
;; let i = haystackLeft;
|
;; let i = haystackLeft;
|
||||||
;; let j = needleLeft;
|
;; let j = needleLeft;
|
||||||
get_local $haystackLeft
|
get_local $haystackLeft
|
||||||
@ -611,10 +588,7 @@
|
|||||||
;; if ( j === needleRight ) { return haystackLeft; }
|
;; if ( j === needleRight ) { return haystackLeft; }
|
||||||
get_local $needleRight
|
get_local $needleRight
|
||||||
i32.eq
|
i32.eq
|
||||||
if
|
br_if $succeed
|
||||||
get_local $haystackLeft
|
|
||||||
return
|
|
||||||
end
|
|
||||||
;; i += 1;
|
;; i += 1;
|
||||||
get_local $i
|
get_local $i
|
||||||
i32.const 1
|
i32.const 1
|
||||||
@ -630,10 +604,15 @@
|
|||||||
tee_local $haystackLeft
|
tee_local $haystackLeft
|
||||||
;; if ( haystackLeft === haystackEnd ) { break; }
|
;; if ( haystackLeft === haystackEnd ) { break; }
|
||||||
get_local $haystackEnd
|
get_local $haystackEnd
|
||||||
i32.ne
|
i32.eq
|
||||||
br_if $mainLoop
|
br_if $fail
|
||||||
|
br $mainLoop
|
||||||
;; }
|
;; }
|
||||||
end end
|
end
|
||||||
|
end ;; $succeed
|
||||||
|
get_local $haystackLeft
|
||||||
|
return
|
||||||
|
end ;; $fail
|
||||||
;; return -1;
|
;; return -1;
|
||||||
i32.const -1
|
i32.const -1
|
||||||
)
|
)
|
||||||
@ -656,6 +635,8 @@
|
|||||||
(local $i i32)
|
(local $i i32)
|
||||||
(local $j i32)
|
(local $j i32)
|
||||||
(local $c0 i32)
|
(local $c0 i32)
|
||||||
|
block $fail
|
||||||
|
block $succeed
|
||||||
;; let haystackLeft = haystackEnd - needleLen;
|
;; let haystackLeft = haystackEnd - needleLen;
|
||||||
get_local $haystackEnd
|
get_local $haystackEnd
|
||||||
get_local $needleLen
|
get_local $needleLen
|
||||||
@ -664,10 +645,7 @@
|
|||||||
;; if ( haystackLeft < haystackBeg ) { return -1; }
|
;; if ( haystackLeft < haystackBeg ) { return -1; }
|
||||||
get_local $haystackBeg
|
get_local $haystackBeg
|
||||||
i32.lt_s
|
i32.lt_s
|
||||||
if
|
br_if $fail
|
||||||
i32.const -1
|
|
||||||
return
|
|
||||||
end
|
|
||||||
;; needleLeft += this.buf32[CHAR0_SLOT];
|
;; needleLeft += this.buf32[CHAR0_SLOT];
|
||||||
get_local $needleLeft
|
get_local $needleLeft
|
||||||
i32.const 2060 ;; CHAR0_SLOT memory address
|
i32.const 2060 ;; CHAR0_SLOT memory address
|
||||||
@ -680,7 +658,7 @@
|
|||||||
set_local $needleRight
|
set_local $needleRight
|
||||||
;; const charCodes = this.buf8;
|
;; const charCodes = this.buf8;
|
||||||
;; for (;;) {
|
;; for (;;) {
|
||||||
block $breakMainLoop loop $mainLoop
|
loop $mainLoop
|
||||||
;; let i = haystackLeft;
|
;; let i = haystackLeft;
|
||||||
;; let j = needleLeft;
|
;; let j = needleLeft;
|
||||||
get_local $haystackLeft
|
get_local $haystackLeft
|
||||||
@ -703,10 +681,7 @@
|
|||||||
;; if ( j === needleRight ) { return haystackLeft; }
|
;; if ( j === needleRight ) { return haystackLeft; }
|
||||||
get_local $needleRight
|
get_local $needleRight
|
||||||
i32.eq
|
i32.eq
|
||||||
if
|
br_if $succeed
|
||||||
get_local $haystackLeft
|
|
||||||
return
|
|
||||||
end
|
|
||||||
;; i += 1;
|
;; i += 1;
|
||||||
get_local $i
|
get_local $i
|
||||||
i32.const 1
|
i32.const 1
|
||||||
@ -720,14 +695,18 @@
|
|||||||
get_local $haystackLeft
|
get_local $haystackLeft
|
||||||
get_local $haystackBeg
|
get_local $haystackBeg
|
||||||
i32.eq
|
i32.eq
|
||||||
br_if $breakMainLoop
|
br_if $fail
|
||||||
get_local $haystackLeft
|
get_local $haystackLeft
|
||||||
i32.const 1
|
i32.const 1
|
||||||
i32.sub
|
i32.sub
|
||||||
set_local $haystackLeft
|
set_local $haystackLeft
|
||||||
br $mainLoop
|
br $mainLoop
|
||||||
;; }
|
;; }
|
||||||
end end
|
end
|
||||||
|
end ;; $succeed
|
||||||
|
get_local $haystackLeft
|
||||||
|
return
|
||||||
|
end ;; $fail
|
||||||
;; return -1;
|
;; return -1;
|
||||||
i32.const -1
|
i32.const -1
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user