mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-25 11:52:51 +01:00
Fix Promise chain of WASM module load operations
The Promise chain was not properly designed for WASM module loading. This became apparent when removing WASM modules from Opera build[1]. The problem was that errors thrown by fetch() -- used to load WASM modules -- were not properly handled. [1] Opera refuses updating uBO if there are unrecognized file types in the package, and `.wasm`/`.wat` files are not recognized by Opera uploader.
This commit is contained in:
parent
4f3aed6fe6
commit
69c87c5117
@ -154,9 +154,9 @@ HNTrieContainer.prototype = {
|
||||
if ( HNTrieContainer.wasmModulePromise instanceof Promise === false ) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return HNTrieContainer.wasmModulePromise.then(module => {
|
||||
return this.initWASM(module);
|
||||
});
|
||||
return HNTrieContainer.wasmModulePromise.then(
|
||||
module => this.initWASM(module)
|
||||
);
|
||||
},
|
||||
|
||||
setNeedle: function(needle) {
|
||||
@ -674,10 +674,13 @@ HNTrieContainer.prototype.HNTrieRef.prototype = {
|
||||
workingDir = url.href;
|
||||
}
|
||||
|
||||
HNTrieContainer.wasmModulePromise = WebAssembly.compileStreaming(
|
||||
fetch(workingDir + 'wasm/hntrie.wasm')
|
||||
HNTrieContainer.wasmModulePromise = fetch(
|
||||
workingDir + 'wasm/hntrie.wasm',
|
||||
{ mode: 'same-origin' }
|
||||
).then(
|
||||
WebAssembly.compileStreaming
|
||||
).catch(reason => {
|
||||
HNTrieContainer.wasmModulePromise = null;
|
||||
console.error(reason);
|
||||
console.info(reason);
|
||||
});
|
||||
})();
|
||||
|
@ -43,7 +43,7 @@ let ttlCount = 0;
|
||||
let ttlTimer;
|
||||
let ttlDelay = 60000;
|
||||
|
||||
let init = function() {
|
||||
const init = function() {
|
||||
ttlDelay = µBlock.hiddenSettings.autoUpdateAssetFetchPeriod * 1000 + 15000;
|
||||
if ( lz4CodecInstance === null ) {
|
||||
return Promise.resolve(null);
|
||||
@ -72,7 +72,7 @@ let init = function() {
|
||||
// which will cause the wasm instance to be forgotten after enough
|
||||
// time elapse without the instance being used.
|
||||
|
||||
let destroy = function() {
|
||||
const destroy = function() {
|
||||
//if ( lz4CodecInstance !== undefined ) {
|
||||
// console.info(
|
||||
// 'uBO: freeing lz4-block-codec instance (%s KB)',
|
||||
@ -85,7 +85,7 @@ let destroy = function() {
|
||||
ttlTimer = undefined;
|
||||
};
|
||||
|
||||
let ttlManage = function(count) {
|
||||
const ttlManage = function(count) {
|
||||
if ( ttlTimer !== undefined ) {
|
||||
clearTimeout(ttlTimer);
|
||||
ttlTimer = undefined;
|
||||
@ -96,7 +96,7 @@ let ttlManage = function(count) {
|
||||
ttlTimer = vAPI.setTimeout(destroy, ttlDelay);
|
||||
};
|
||||
|
||||
let uint8ArrayFromBlob = function(key, data) {
|
||||
const uint8ArrayFromBlob = function(key, data) {
|
||||
if ( data instanceof Blob === false ) {
|
||||
return Promise.resolve({ key, data });
|
||||
}
|
||||
@ -109,7 +109,7 @@ let uint8ArrayFromBlob = function(key, data) {
|
||||
});
|
||||
};
|
||||
|
||||
let encodeValue = function(key, value) {
|
||||
const encodeValue = function(key, value) {
|
||||
if ( !lz4CodecInstance ) { return; }
|
||||
//let t0 = window.performance.now();
|
||||
if ( textEncoder === undefined ) {
|
||||
@ -138,7 +138,7 @@ let encodeValue = function(key, value) {
|
||||
return outputArray;
|
||||
};
|
||||
|
||||
let decodeValue = function(key, inputArray) {
|
||||
const decodeValue = function(key, inputArray) {
|
||||
if ( !lz4CodecInstance ) { return; }
|
||||
//let t0 = window.performance.now();
|
||||
if (
|
||||
|
@ -46,7 +46,7 @@
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
let wd = (function() {
|
||||
const wd = (function() {
|
||||
let url = document.currentScript.src;
|
||||
let match = /[^\/]+$/.exec(url);
|
||||
return match !== null ?
|
||||
@ -54,38 +54,31 @@ let wd = (function() {
|
||||
'';
|
||||
})();
|
||||
|
||||
let removeScript = function(script) {
|
||||
const removeScript = function(script) {
|
||||
if ( !script ) { return; }
|
||||
if ( script.parentNode === null ) { return; }
|
||||
script.parentNode.removeChild(script);
|
||||
};
|
||||
|
||||
let createInstanceWASM = function() {
|
||||
const createInstanceWASM = function() {
|
||||
if ( context.LZ4BlockWASM instanceof Function ) {
|
||||
let instance = new context.LZ4BlockWASM();
|
||||
return instance.init().then(( ) => { return instance; });
|
||||
const instance = new context.LZ4BlockWASM();
|
||||
return instance.init().then(ok => ok ? instance : null);
|
||||
}
|
||||
if ( context.LZ4BlockWASM === null ) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let script = document.createElement('script');
|
||||
return new Promise(resolve => {
|
||||
const script = document.createElement('script');
|
||||
script.src = wd + 'lz4-block-codec-wasm.js';
|
||||
script.addEventListener('load', ( ) => {
|
||||
if ( context.LZ4BlockWASM instanceof Function === false ) {
|
||||
context.LZ4BlockWASM = null;
|
||||
context.LZ4BlockWASM = undefined;
|
||||
resolve(null);
|
||||
} else {
|
||||
let instance = new context.LZ4BlockWASM();
|
||||
instance.init()
|
||||
.then(( ) => {
|
||||
resolve(instance);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
const instance = new context.LZ4BlockWASM();
|
||||
instance.init().then(ok => { resolve(ok ? instance : null); });
|
||||
});
|
||||
script.addEventListener('error', ( ) => {
|
||||
context.LZ4BlockWASM = null;
|
||||
@ -96,31 +89,25 @@ let createInstanceWASM = function() {
|
||||
});
|
||||
};
|
||||
|
||||
let createInstanceJS = function() {
|
||||
const createInstanceJS = function() {
|
||||
if ( context.LZ4BlockJS instanceof Function ) {
|
||||
let instance = new context.LZ4BlockJS();
|
||||
return instance.init().then(( ) => { return instance; });
|
||||
const instance = new context.LZ4BlockJS();
|
||||
return instance.init().then(ok => ok ? instance : null);
|
||||
}
|
||||
if ( context.LZ4BlockJS === null ) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let script = document.createElement('script');
|
||||
return new Promise(resolve => {
|
||||
const script = document.createElement('script');
|
||||
script.src = wd + 'lz4-block-codec-js.js';
|
||||
script.addEventListener('load', ( ) => {
|
||||
if ( context.LZ4BlockJS instanceof Function === false ) {
|
||||
context.LZ4BlockJS = null;
|
||||
resolve(null);
|
||||
} else {
|
||||
let instance = new context.LZ4BlockJS();
|
||||
instance.init()
|
||||
.then(( ) => {
|
||||
resolve(instance);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
const instance = new context.LZ4BlockJS();
|
||||
instance.init().then(ok => { resolve(ok ? instance : null); });
|
||||
});
|
||||
script.addEventListener('error', ( ) => {
|
||||
context.LZ4BlockJS = null;
|
||||
@ -143,20 +130,13 @@ context.lz4BlockCodec = {
|
||||
} else {
|
||||
instantiator = createInstanceWASM || createInstanceJS;
|
||||
}
|
||||
return (instantiator)()
|
||||
.then(instance => {
|
||||
if ( instance ) { return instance; }
|
||||
if ( flavor === undefined ) {
|
||||
return createInstanceJS();
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.catch(( ) => {
|
||||
if ( flavor === undefined ) {
|
||||
return createInstanceJS();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return (instantiator)().then(instance => {
|
||||
if ( instance ) { return instance; }
|
||||
if ( flavor === undefined ) {
|
||||
return createInstanceJS();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
},
|
||||
reset: function() {
|
||||
context.LZ4BlockWASM = undefined;
|
||||
|
@ -46,7 +46,7 @@
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
let growOutputBuffer = function(instance, size) {
|
||||
const growOutputBuffer = function(instance, size) {
|
||||
if (
|
||||
instance.outputBuffer === undefined ||
|
||||
instance.outputBuffer.byteLength < size
|
||||
@ -56,13 +56,13 @@ let growOutputBuffer = function(instance, size) {
|
||||
return instance.outputBuffer;
|
||||
};
|
||||
|
||||
let encodeBound = function(size) {
|
||||
const encodeBound = function(size) {
|
||||
return size > 0x7E000000 ?
|
||||
0 :
|
||||
size + (size / 255 | 0) + 16;
|
||||
};
|
||||
|
||||
let encodeBlock = function(instance, iBuf, oOffset) {
|
||||
const encodeBlock = function(instance, iBuf, oOffset) {
|
||||
let iLen = iBuf.byteLength;
|
||||
if ( iLen >= 0x7E000000 ) { throw new RangeError(); }
|
||||
|
||||
@ -183,7 +183,7 @@ let encodeBlock = function(instance, iBuf, oOffset) {
|
||||
return new Uint8Array(oBuf.buffer, 0, oPos);
|
||||
};
|
||||
|
||||
let decodeBlock = function(instance, iBuf, iOffset, oLen) {
|
||||
const decodeBlock = function(instance, iBuf, iOffset, oLen) {
|
||||
let iLen = iBuf.byteLength;
|
||||
let oBuf = new Uint8Array(growOutputBuffer(instance, oLen), 0, oLen);
|
||||
let iPos = iOffset, oPos = 0;
|
||||
@ -252,7 +252,7 @@ context.LZ4BlockJS = function() {
|
||||
context.LZ4BlockJS.prototype = {
|
||||
flavor: 'js',
|
||||
init: function() {
|
||||
return Promise.resolve();
|
||||
return Promise.resolve(true);
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
let wd = (function() {
|
||||
const wd = (function() {
|
||||
let url = document.currentScript.src;
|
||||
let match = /[^\/]+$/.exec(url);
|
||||
return match !== null ?
|
||||
@ -56,7 +56,7 @@ let wd = (function() {
|
||||
'';
|
||||
})();
|
||||
|
||||
let growMemoryTo = function(wasmInstance, byteLength) {
|
||||
const growMemoryTo = function(wasmInstance, byteLength) {
|
||||
let lz4api = wasmInstance.exports;
|
||||
let neededByteLength = lz4api.getLinearMemoryOffset() + byteLength;
|
||||
let pageCountBefore = lz4api.memory.buffer.byteLength >>> 16;
|
||||
@ -67,7 +67,7 @@ let growMemoryTo = function(wasmInstance, byteLength) {
|
||||
return lz4api.memory.buffer;
|
||||
};
|
||||
|
||||
let encodeBlock = function(wasmInstance, inputArray, outputOffset) {
|
||||
const encodeBlock = function(wasmInstance, inputArray, outputOffset) {
|
||||
let lz4api = wasmInstance.exports;
|
||||
let mem0 = lz4api.getLinearMemoryOffset();
|
||||
let hashTableSize = 65536 * 4;
|
||||
@ -96,7 +96,7 @@ let encodeBlock = function(wasmInstance, inputArray, outputOffset) {
|
||||
return outputArray;
|
||||
};
|
||||
|
||||
let decodeBlock = function(wasmInstance, inputArray, inputOffset, outputSize) {
|
||||
const decodeBlock = function(wasmInstance, inputArray, inputOffset, outputSize) {
|
||||
let inputSize = inputArray.byteLength;
|
||||
let lz4api = wasmInstance.exports;
|
||||
let mem0 = lz4api.getLinearMemoryOffset();
|
||||
@ -130,24 +130,25 @@ context.LZ4BlockWASM.prototype = {
|
||||
this.lz4wasmInstance = null;
|
||||
}
|
||||
if ( this.lz4wasmInstance === null ) {
|
||||
return Promise.reject();
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
if ( this.lz4wasmInstance instanceof WebAssembly.Instance ) {
|
||||
return Promise.resolve(this.lz4wasmInstance);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
if ( this.lz4wasmInstance === undefined ) {
|
||||
this.lz4wasmInstance = WebAssembly.instantiateStreaming(
|
||||
fetch(wd + 'lz4-block-codec.wasm', { mode: 'same-origin' })
|
||||
this.lz4wasmInstance = fetch(
|
||||
wd + 'lz4-block-codec.wasm',
|
||||
{ mode: 'same-origin' }
|
||||
).then(
|
||||
WebAssembly.instantiateStreaming
|
||||
).then(result => {
|
||||
this.lz4wasmInstance = undefined;
|
||||
this.lz4wasmInstance = result && result.instance || null;
|
||||
if ( this.lz4wasmInstance !== null ) { return this; }
|
||||
return null;
|
||||
});
|
||||
this.lz4wasmInstance.catch(( ) => {
|
||||
}).catch(reason => {
|
||||
this.lz4wasmInstance = null;
|
||||
return null;
|
||||
});
|
||||
console.info(reason);
|
||||
}).then(( ) =>
|
||||
this.lz4wasmInstance !== null
|
||||
);
|
||||
}
|
||||
return this.lz4wasmInstance;
|
||||
},
|
||||
|
@ -46,6 +46,15 @@ rm -r $DES/_locales/mr
|
||||
rm -r $DES/_locales/ta
|
||||
rm -r $DES/_locales/th
|
||||
|
||||
# Removing WASM modules until I receive an answer from Opera people: Opera's
|
||||
# uploader issue an error for hntrie.wasm and this prevents me from
|
||||
# updating uBO in the Opera store. The modules are unused anyway for
|
||||
# Chromium- based browsers.
|
||||
rm $DES/js/wasm/*.wasm
|
||||
rm $DES/js/wasm/*.wat
|
||||
rm $DES/lib/lz4/*.wasm
|
||||
rm $DES/lib/lz4/*.wat
|
||||
|
||||
echo "*** uBlock0.opera: Generating web accessible resources..."
|
||||
cp -R src/web_accessible_resources $DES/
|
||||
python3 tools/import-war.py $DES/
|
||||
|
Loading…
Reference in New Issue
Block a user