summaryrefslogtreecommitdiffstats
path: root/src/lib/publicsuffixlist/wasm
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 05:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 05:47:55 +0000
commit31d6ff6f931696850c348007241195ab3b2eddc7 (patch)
tree615cb1c57ce9f6611bad93326b9105098f379609 /src/lib/publicsuffixlist/wasm
parentInitial commit. (diff)
downloadublock-origin-31d6ff6f931696850c348007241195ab3b2eddc7.tar.xz
ublock-origin-31d6ff6f931696850c348007241195ab3b2eddc7.zip
Adding upstream version 1.55.0+dfsg.upstream/1.55.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/publicsuffixlist/wasm')
-rw-r--r--src/lib/publicsuffixlist/wasm/README.md29
-rw-r--r--src/lib/publicsuffixlist/wasm/publicsuffixlist.wasmbin0 -> 408 bytes
-rw-r--r--src/lib/publicsuffixlist/wasm/publicsuffixlist.wat322
3 files changed, 351 insertions, 0 deletions
diff --git a/src/lib/publicsuffixlist/wasm/README.md b/src/lib/publicsuffixlist/wasm/README.md
new file mode 100644
index 0000000..5c1c483
--- /dev/null
+++ b/src/lib/publicsuffixlist/wasm/README.md
@@ -0,0 +1,29 @@
+### For code reviewers
+
+All `wasm` files in that directory where created by compiling the
+corresponding `wat` file using the command (using
+`publicsuffixlist.wat`/`publicsuffixlist.wasm` as example):
+
+ wat2wasm publicsuffixlist.wat -o publicsuffixlist.wasm
+
+Assuming:
+
+- The command is executed from within the present directory.
+
+### `wat2wasm` tool
+
+The `wat2wasm` tool can be downloaded from an official WebAssembly project:
+<https://github.com/WebAssembly/wabt/releases>.
+
+### `wat2wasm` tool online
+
+You can also use the following online `wat2wasm` tool:
+<https://webassembly.github.io/wabt/demo/wat2wasm/>.
+
+Just paste the whole content of the `wat` file to compile into the WAT pane.
+Click "Download" button to retrieve the resulting `wasm` file.
+
+### See also
+
+For the curious, the following online tool allows you to find out the machine
+code as a result from the WASM code: https://mbebenita.github.io/WasmExplorer/
diff --git a/src/lib/publicsuffixlist/wasm/publicsuffixlist.wasm b/src/lib/publicsuffixlist/wasm/publicsuffixlist.wasm
new file mode 100644
index 0000000..1f7ca0c
--- /dev/null
+++ b/src/lib/publicsuffixlist/wasm/publicsuffixlist.wasm
Binary files differ
diff --git a/src/lib/publicsuffixlist/wasm/publicsuffixlist.wat b/src/lib/publicsuffixlist/wasm/publicsuffixlist.wat
new file mode 100644
index 0000000..8ea7381
--- /dev/null
+++ b/src/lib/publicsuffixlist/wasm/publicsuffixlist.wat
@@ -0,0 +1,322 @@
+;;
+;; uBlock Origin - a browser extension to block requests.
+;; Copyright (C) 2019-present Raymond Hill
+;;
+;; License: pick the one which suits you:
+;; GPL v3 see <https://www.gnu.org/licenses/gpl.html>
+;; APL v2 see <http://www.apache.org/licenses/LICENSE-2.0>
+;;
+;; Home: https://github.com/gorhill/publicsuffixlist.js
+;; File: publicsuffixlist.wat
+;;
+;; Description: WebAssembly implementation for core lookup method in
+;; publicsuffixlist.js
+;;
+;; How to compile:
+;;
+;; wat2wasm publicsuffixlist.wat -o publicsuffixlist.wasm
+;;
+;; The `wat2wasm` tool can be downloaded from an official WebAssembly
+;; project:
+;; https://github.com/WebAssembly/wabt/releases
+
+
+(module
+;;
+;; module start
+;;
+
+(memory (import "imports" "memory") 1)
+
+;;
+;; Tree encoding in array buffer:
+;;
+;; Node:
+;; + u8: length of char data
+;; + u8: flags => bit 0: is_publicsuffix, bit 1: is_exception
+;; + u16: length of array of children
+;; + u32: char data or offset to char data
+;; + u32: offset to array of children
+;; = 12 bytes
+;;
+;; // i32 / i8
+;; const HOSTNAME_SLOT = 0; // jshint ignore:line
+;; const LABEL_INDICES_SLOT = 256; // -- / 256
+;; const RULES_PTR_SLOT = 100; // 100 / 400
+;; const SUFFIX_NOT_FOUND_SLOT = 399; // -- / 399
+;; const CHARDATA_PTR_SLOT = 101; // 101 / 404
+;; const EMPTY_STRING = '';
+;; const SELFIE_MAGIC = 2;
+;;
+
+;;
+;; Public functions
+;;
+
+;;
+;; unsigned int getPublicSuffixPos()
+;;
+;; Returns an offset to the start of the public suffix.
+;;
+(func (export "getPublicSuffixPos")
+ (result i32) ;; result = match index, -1 = miss
+ (local $iCharData i32) ;; offset to start of character data
+ (local $iNode i32) ;; offset to current node
+ (local $iLabel i32) ;; offset to label indices
+ (local $cursorPos i32) ;; position of cursor within hostname argument
+ (local $labelBeg i32)
+ (local $labelLen i32)
+ (local $nCandidates i32)
+ (local $iCandidates i32)
+ (local $iFound i32)
+ (local $l i32)
+ (local $r i32)
+ (local $d i32)
+ (local $iCandidate i32)
+ (local $iCandidateNode i32)
+ (local $candidateLen i32)
+ (local $iCandidateChar i32)
+ (local $_1 i32)
+ (local $_2 i32)
+ (local $_3 i32)
+ ;;
+ ;; const iCharData = buf32[CHARDATA_PTR_SLOT];
+ i32.const 404
+ i32.load
+ local.set $iCharData
+ ;; let iNode = pslBuffer32[RULES_PTR_SLOT];
+ i32.const 400
+ i32.load
+ i32.const 2
+ i32.shl
+ local.set $iNode
+ ;; let iLabel = LABEL_INDICES_SLOT;
+ i32.const 256
+ local.set $iLabel
+ ;; let cursorPos = -1;
+ i32.const -1
+ local.set $cursorPos
+ ;; label-lookup loop
+ ;; for (;;) {
+ block $labelLookupDone loop $labelLookup
+ ;; // Extract label indices
+ ;; const labelBeg = buf8[iLabel+1];
+ ;; const labelLen = buf8[iLabel+0] - labelBeg;
+ local.get $iLabel
+ i32.load8_u
+ local.get $iLabel
+ i32.load8_u offset=1
+ local.tee $labelBeg
+ i32.sub
+ local.set $labelLen
+ ;; // Match-lookup loop: binary search
+ ;; let r = buf32[iNode+0] >>> 16;
+ ;; if ( r === 0 ) { break; }
+ local.get $iNode
+ i32.load16_u offset=2
+ local.tee $r
+ i32.eqz
+ br_if $labelLookupDone
+ ;; const iCandidates = buf32[iNode+2];
+ local.get $iNode
+ i32.load offset=8
+ i32.const 2
+ i32.shl
+ local.set $iCandidates
+ ;; let l = 0;
+ ;; let iFound = 0;
+ i32.const 0
+ local.tee $l
+ local.set $iFound
+ ;; while ( l < r ) {
+ block $binarySearchDone loop $binarySearch
+ local.get $l
+ local.get $r
+ i32.ge_u
+ br_if $binarySearchDone
+ ;; const iCandidate = l + r >>> 1;
+ local.get $l
+ local.get $r
+ i32.add
+ i32.const 1
+ i32.shr_u
+ local.tee $iCandidate
+ ;; const iCandidateNode = iCandidates + iCandidate + (iCandidate << 1);
+ i32.const 2
+ i32.shl
+ local.tee $_1
+ local.get $_1
+ i32.const 1
+ i32.shl
+ i32.add
+ local.get $iCandidates
+ i32.add
+ local.tee $iCandidateNode
+ ;; const candidateLen = buf32[iCandidateNode+0] & 0x000000FF;
+ i32.load8_u
+ local.set $candidateLen
+ ;; let d = labelLen - candidateLen;
+ local.get $labelLen
+ local.get $candidateLen
+ i32.sub
+ local.tee $d
+ ;; if ( d === 0 ) {
+ i32.eqz
+ if
+ ;; const iCandidateChar = candidateLen <= 4
+ local.get $candidateLen
+ i32.const 4
+ i32.le_u
+ if
+ ;; ? iCandidateNode + 1 << 2
+ local.get $iCandidateNode
+ i32.const 4
+ i32.add
+ local.set $iCandidateChar
+ else
+ ;; : buf32[CHARDATA_PTR_SLOT] + buf32[iCandidateNode+1];
+ local.get $iCharData
+ local.get $iCandidateNode
+ i32.load offset=4
+ i32.add
+ local.set $iCandidateChar
+ end
+ ;; for ( let i = 0; i < labelLen; i++ ) {
+ local.get $labelBeg
+ local.tee $_1
+ local.get $labelLen
+ i32.add
+ local.set $_3
+ local.get $iCandidateChar
+ local.set $_2
+ block $findDiffDone loop $findDiff
+ ;; d = buf8[labelBeg+i] - buf8[iCandidateChar+i];
+ ;; if ( d !== 0 ) { break; }
+ local.get $_1
+ i32.load8_u
+ local.get $_2
+ i32.load8_u
+ i32.sub
+ local.tee $d
+ br_if $findDiffDone
+ local.get $_1
+ i32.const 1
+ i32.add
+ local.tee $_1
+ local.get $_3
+ i32.eq
+ br_if $findDiffDone
+ local.get $_2
+ i32.const 1
+ i32.add
+ local.set $_2
+ br $findDiff
+ ;; }
+ end end
+ ;; }
+ end
+ ;; if ( d < 0 ) {
+ ;; r = iCandidate;
+ local.get $d
+ i32.const 0
+ i32.lt_s
+ if
+ local.get $iCandidate
+ local.set $r
+ br $binarySearch
+ end
+ ;; } else if ( d > 0 ) {
+ ;; l = iCandidate + 1;
+ local.get $d
+ i32.const 0
+ i32.gt_s
+ if
+ local.get $iCandidate
+ i32.const 1
+ i32.add
+ local.set $l
+ br $binarySearch
+ end
+ ;; } else /* if ( d === 0 ) */ {
+ ;; iFound = iCandidateNode;
+ ;; break;
+ ;; }
+ local.get $iCandidateNode
+ local.set $iFound
+ end end
+ ;; }
+ ;; // 2. If no rules match, the prevailing rule is "*".
+ ;; if ( iFound === 0 ) {
+ ;; if ( buf32[iCandidates + 1] !== 0x2A /* '*' */ ) { break; }
+ ;; buf8[SUFFIX_NOT_FOUND_SLOT] = 1;
+ ;; iFound = iCandidates;
+ ;; }
+ local.get $iFound
+ i32.eqz
+ if
+ local.get $iCandidates
+ i32.load offset=4
+ i32.const 0x2A
+ i32.ne
+ br_if $labelLookupDone
+ i32.const 399
+ i32.const 1
+ i32.store8
+ local.get $iCandidates
+ local.set $iFound
+ end
+ ;; iNode = iFound;
+ local.get $iFound
+ local.tee $iNode
+ ;; // 5. If the prevailing rule is a exception rule, modify it by
+ ;; // removing the leftmost label.
+ ;; if ( (buf32[iNode+0] & 0x00000200) !== 0 ) {
+ ;; if ( iLabel > LABEL_INDICES_SLOT ) {
+ ;; return iLabel - 2;
+ ;; }
+ ;; break;
+ ;; }
+ i32.load8_u offset=1
+ local.tee $_1
+ i32.const 0x02
+ i32.and
+ if
+ local.get $iLabel
+ i32.const 256
+ i32.gt_u
+ if
+ local.get $iLabel
+ i32.const -2
+ i32.add
+ return
+ end
+ br $labelLookupDone
+ end
+ ;; if ( (buf32[iNode+0] & 0x00000100) !== 0 ) {
+ ;; cursorPos = labelBeg;
+ ;; }
+ local.get $_1
+ i32.const 0x01
+ i32.and
+ if
+ local.get $iLabel
+ local.set $cursorPos
+ end
+ ;; if ( labelBeg === 0 ) { break; }
+ local.get $labelBeg
+ i32.eqz
+ br_if $labelLookupDone
+ ;; iLabel += 2;
+ local.get $iLabel
+ i32.const 2
+ i32.add
+ local.set $iLabel
+ br $labelLookup
+ end end
+ local.get $cursorPos
+)
+
+;;
+;; module end
+;;
+)