tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

polyfill.js (4451B)


      1 // Generate some helper functions for manipulating (array (mut i16)) from JS
      2 let helperExports;
      3 {
      4  const builder = new WasmModuleBuilder();
      5  const arrayIndex = builder.addArray(kWasmI16, true, kNoSuperType, true);
      6 
      7  builder
      8    .addFunction("createArrayMutI16", {
      9      params: [kWasmI32],
     10      results: [kWasmAnyRef]
     11    })
     12    .addBody([
     13      kExprLocalGet,
     14      ...wasmSignedLeb(0),
     15      ...GCInstr(kExprArrayNewDefault),
     16      ...wasmSignedLeb(arrayIndex)
     17      ])
     18    .exportFunc();
     19 
     20  builder
     21    .addFunction("arrayLength", {
     22      params: [kWasmArrayRef],
     23      results: [kWasmI32]
     24    })
     25    .addBody([
     26      kExprLocalGet,
     27      ...wasmSignedLeb(0),
     28      ...GCInstr(kExprArrayLen)
     29      ])
     30    .exportFunc();
     31 
     32  builder
     33    .addFunction("arraySet", {
     34      params: [wasmRefNullType(arrayIndex), kWasmI32, kWasmI32],
     35      results: []
     36    })
     37    .addBody([
     38      kExprLocalGet,
     39      ...wasmSignedLeb(0),
     40      kExprLocalGet,
     41      ...wasmSignedLeb(1),
     42      kExprLocalGet,
     43      ...wasmSignedLeb(2),
     44      ...GCInstr(kExprArraySet),
     45      ...wasmSignedLeb(arrayIndex)
     46      ])
     47    .exportFunc();
     48 
     49  builder
     50    .addFunction("arrayGet", {
     51      params: [wasmRefNullType(arrayIndex), kWasmI32],
     52      results: [kWasmI32]
     53    })
     54    .addBody([
     55      kExprLocalGet,
     56      ...wasmSignedLeb(0),
     57      kExprLocalGet,
     58      ...wasmSignedLeb(1),
     59      ...GCInstr(kExprArrayGetU),
     60      ...wasmSignedLeb(arrayIndex)
     61      ])
     62    .exportFunc();
     63 
     64  let bytes = builder.toBuffer();
     65  let module = new WebAssembly.Module(bytes);
     66  let instance = new WebAssembly.Instance(module);
     67 
     68  helperExports = instance.exports;
     69 }
     70 
     71 function throwIfNotString(a) {
     72  if (typeof a !== "string") {
     73    throw new WebAssembly.RuntimeError();
     74  }
     75 }
     76 
     77 this.polyfillImports = {
     78  test: (string) => {
     79    if (string === null ||
     80        typeof string !== "string") {
     81      return 0;
     82    }
     83    return 1;
     84  },
     85  cast: (string) => {
     86    throwIfNotString(string);
     87    return string;
     88  },
     89  fromCharCodeArray: (array, arrayStart, arrayCount) => {
     90    arrayStart >>>= 0;
     91    arrayCount >>>= 0;
     92    let length = helperExports.arrayLength(array);
     93    if (BigInt(arrayStart) + BigInt(arrayCount) > BigInt(length)) {
     94      throw new WebAssembly.RuntimeError();
     95    }
     96    let result = '';
     97    for (let i = arrayStart; i < arrayStart + arrayCount; i++) {
     98      result += String.fromCharCode(helperExports.arrayGet(array, i));
     99    }
    100    return result;
    101  },
    102  intoCharCodeArray: (string, arr, arrayStart) => {
    103    arrayStart >>>= 0;
    104    throwIfNotString(string);
    105    let arrLength = helperExports.arrayLength(arr);
    106    let stringLength = string.length;
    107    if (BigInt(arrayStart) + BigInt(stringLength) > BigInt(arrLength)) {
    108      throw new WebAssembly.RuntimeError();
    109    }
    110    for (let i = 0; i < stringLength; i++) {
    111      helperExports.arraySet(arr, arrayStart + i, string[i].charCodeAt(0));
    112    }
    113    return stringLength;
    114  },
    115  fromCharCode: (charCode) => {
    116    charCode >>>= 0;
    117    return String.fromCharCode(charCode);
    118  },
    119  fromCodePoint: (codePoint) => {
    120    codePoint >>>= 0;
    121    return String.fromCodePoint(codePoint);
    122  },
    123  charCodeAt: (string, stringIndex) => {
    124    stringIndex >>>= 0;
    125    throwIfNotString(string);
    126    if (stringIndex >= string.length)
    127      throw new WebAssembly.RuntimeError();
    128    return string.charCodeAt(stringIndex);
    129  },
    130  codePointAt: (string, stringIndex) => {
    131    stringIndex >>>= 0;
    132    throwIfNotString(string);
    133    if (stringIndex >= string.length)
    134      throw new WebAssembly.RuntimeError();
    135    return string.codePointAt(stringIndex);
    136  },
    137  length: (string) => {
    138    throwIfNotString(string);
    139    return string.length;
    140  },
    141  concat: (stringA, stringB) => {
    142    throwIfNotString(stringA);
    143    throwIfNotString(stringB);
    144    return stringA + stringB;
    145  },
    146  substring: (string, startIndex, endIndex) => {
    147    startIndex >>>= 0;
    148    endIndex >>>= 0;
    149    throwIfNotString(string);
    150    if (startIndex > string.length,
    151        endIndex > string.length,
    152        endIndex < startIndex) {
    153      return "";
    154    }
    155    return string.substring(startIndex, endIndex);
    156  },
    157  equals: (stringA, stringB) => {
    158    if (stringA !== null) throwIfNotString(stringA);
    159    if (stringB !== null) throwIfNotString(stringB);
    160    return stringA === stringB;
    161  },
    162  compare: (stringA, stringB) => {
    163    throwIfNotString(stringA);
    164    throwIfNotString(stringB);
    165    if (stringA < stringB) {
    166      return -1;
    167    }
    168    return stringA === stringB ? 0 : 1;
    169  },
    170 };