// This script can be customized by setting the following variables in code that
// runs before this script.
//
// The binary to be run. (If not set, we get the filename from argv and read
// from it.)
var binary;
// A second binary to be linked in and run as well. (Can also be read from
// argv.)
var secondBinary;
// Whether we are fuzzing JSPI. In addition to this being set, the "async" and
// "await" keywords must be taken out of the /* KEYWORD */ comments (which they
// are normally in, so as not to affect normal fuzzing).
var JSPI;

// Shell integration: find argv and set up readBinary().
var argv;
var readBinary;
if (typeof process === 'object' && typeof require === 'function') {
  // Node.js.
  argv = process.argv.slice(2);
  readBinary = function(name) {
    var data = require('fs').readFileSync(name);
    if (!data.buffer) data = new Uint8Array(data);
    return data;
  };
} else {
  // A shell like D8.
  if (typeof scriptArgs != 'undefined') {
    argv = scriptArgs;
  } else if (typeof arguments != 'undefined') {
    argv = arguments;
  }
  readBinary = function(name) {
    if (typeof readbuffer === 'function') {
      return new Uint8Array(readbuffer(name));
    } else {
      return read(name, 'binary');
    }
  };
}

if (!binary) {
  binary = readBinary(argv[0]);
}

// Normally we call all the exports of the given wasm file. But, if we are
// passed a final parameter in the form of "exports:X,Y,Z" then we call
// specifically the exports X, Y, and Z.
var exportsToCall;

// Passing --fuzz-split makes us treat the two input files as split off
// from a single one, and we will run them as that single file (ignoring extra
// exports from the second one, and from wasm-split itself). This allows us to
// get the same behavior from split modules as before the split.
var fuzzSplit = false;

for (var i = 0; i < argv.length; i++) {
  var curr = argv[i];
  if (curr.startsWith('exports:')) {
    exportsToCall = curr.substr('exports:'.length).split(',');
    argv.splice(i, 1);
    i--;
  } else if (curr == '--fuzz-split') {
    fuzzSplit = true;
    argv.splice(i, 1);
    i--;
  }
}

// If a second parameter is given, it is a second binary that we will link in
// with it.
if (argv[1]) {
  secondBinary = readBinary(argv[1]);
}

// Utilities.
function assert(x, y) {
  if (!x) throw (y || 'assertion failed');// + new Error().stack;
}

// Print out a value in a way that works well for fuzzing.
function printed(x, y) {
  if (typeof y !== 'undefined') {
    // A pair of i32s which are a legalized i64.
    return x + ' ' + y;
  } else if (x === null) {
    // JS has just one null. Print that out rather than typeof null which is
    // 'object', below.
    return 'null';
  } else if (typeof x === 'string') {
    // Emit a string in the same format as the binaryen interpreter. This
    // escaping routine must be kept in sync with String::printEscapedJSON.
    var escaped = '';
    for (u of x) {
      switch (u) {
        case '"':
          escaped += '\\"';
          continue;
        case '\\':
          escaped += '\\\\';
          continue;
        case '\b':
          escaped += '\\b';
          continue;
        case '\f':
          escaped += '\\f';
          continue;
        case '\n':
          escaped += '\\n';
          continue;
        case '\r':
          escaped += '\\r';
          continue;
        case '\t':
          escaped += '\\t';
          continue;
        default:
          break;
      }

      var codePoint = u.codePointAt(0);
      if (32 <= codePoint && codePoint < 127) {
        escaped += u;
        continue
      }

      var printEscape = (codePoint) => {
        escaped += '\\u'
        escaped += ((codePoint & 0xF000) >> 12).toString(16);
        escaped += ((codePoint & 0x0F00) >> 8).toString(16);
        escaped += ((codePoint & 0x00F0) >> 4).toString(16);
        escaped += (codePoint & 0x000F).toString(16);
      };

      if (codePoint < 0x10000) {
        printEscape(codePoint);
      } else {
        printEscape(0xD800 + ((codePoint - 0x10000) >> 10));
        printEscape(0xDC00 + ((codePoint - 0x10000) & 0x3FF));
      }
    }
    return 'string("' + escaped + '")';
  } else if (typeof x === 'bigint') {
    // Print bigints in legalized form, which is two 32-bit numbers of the low
    // and high bits.
    return (Number(x & 0xffffffffn) | 0) + ' ' + (Number(x >> 32n) | 0)
  } else if (typeof x !== 'number') {
    // Something that is not a number or string, like a reference. We can't
    // print a reference because it could look different after opts - imagine
    // that a function gets renamed internally (that is, the problem is that
    // JS printing will emit some info about the reference and not a stable
    // external representation of it). In those cases just print the type,
    // which will be 'object' or 'function'.
    return typeof x;
  } else {
    // A number. Print the whole thing.
    return '' + x;
  }
}

// Fuzzer integration.
function logValue(x, y) {
  console.log('[LoggingExternalInterface logging ' + printed(x, y) + ']');
}

function logRef(ref) {
  // Look for VM bugs by using the reference in an API (note: we cannot do
  // +ref or ref+'' as those trap).
  JSON.stringify(ref);
  // If not null, try to read a property, which might exercise an
  // interesting code path.
  if (ref) {
    ref.foobar;
  }
  // Finally, log normally as with all other loggers.
  logValue(ref);
}

// Track the exports in a map (similar to the Exports object from wasm, i.e.,
// whose keys are strings and whose values are the corresponding exports).
var exports = {};

// Also track exports in a list, to allow access by index. Each entry here will
// be in the form of { name: .., value: .. }. That allows us to log the name of
// the function and also to call it. This is important because different
// functions may have the same name, if they were exported by different
// Instances under the same export names.
var exportList = [];

// Given a wasm function, call it as best we can from JS, and return the result.
function callFunc(func) {
  // Send the function a null for each parameter. Null can be converted without
  // error to both a number and a reference.
  var args = [];
  for (var i = 0; i < func.length; i++) {
    args.push(null);
  }
  return func.apply(null, args);
}

// Calls a given function in a try-catch. Return 1 if an exception was thrown.
// If |rethrow| is set, and an exception is thrown, it is caught and rethrown.
// Wasm traps are not swallowed (see details below).
/* async */ function tryCall(func, rethrow) {
  try {
    /* await */ func();
    return 0;
  } catch (e) {
    // The exception might be a JS null, but otherwise it must be valid to check
    // if a property exists on it (VM bugs could cause errors here, specifically
    // if a wasm exception is caught here, and it is not represented properly).
    if (e !== null) e.a;

    // We only want to catch exceptions, not wasm traps: traps should still
    // halt execution. Handling this requires different code in wasm2js, so
    // check for that first (wasm2js does not define RuntimeError, so use
    // that for the check - when wasm2js is run, we override the entire
    // WebAssembly object with a polyfill, so we know exactly what it
    // contains).
    var wasm2js = !WebAssembly.RuntimeError;
    if (!wasm2js) {
      // When running native wasm, we can detect wasm traps.
      if (e instanceof WebAssembly.RuntimeError) {
        throw e;
      }
    }
    var text = e + '';
    // We must not swallow host limitations here: a host limitation is a
    // problem that means we must not compare the outcome here to any other
    // VM.
    var hostIssues = ['requested new array is too large',
                      'out of memory',
                      'Maximum call stack size exceeded'];
    if (wasm2js) {
      // When wasm2js does trap, it just throws an "abort" error.
      hostIssues.push('abort');
    }
    for (var hostIssue of hostIssues) {
      if (text.includes(hostIssue)) {
        throw e;
      }
    }
    // Otherwise, this is a normal exception we want to catch (a wasm
    // exception, or a conversion error on the wasm/JS boundary, etc.). Rethrow
    // if we were asked to.
    if (rethrow) {
      throw e;
    }
    return 1;
  }
}

// Table get/set operations need a BigInt if the table has 64-bit indexes. This
// adds a proper cast as needed.
function toAddressType(table, index) {
  // First, cast to unsigned. We do not support larger indexes anyhow.
  index = index >>> 0;
  if (typeof table.length == 'bigint') {
    return BigInt(index);
  }
  return index;
}

// Simple deterministic hashing, on an unsigned 32-bit seed. See e.g.
// https://www.boost.org/doc/libs/1_55_0/doc/html/hash/reference.html#boost.hash_combine
var hashSeed;

function hasHashSeed() {
  return hashSeed !== undefined;
}

function hashCombine(value) {
  // hashSeed must be set before we do anything.
  assert(hasHashSeed());

  hashSeed ^= value + 0x9e3779b9 + (hashSeed << 6) + (hashSeed >>> 2);
  return hashSeed >>> 0;
}

// Get a random 32-bit number. This is like hashCombine but does not take a
// parameter.
function randomBits() {
  return hashCombine(-1);
}

// Return true with probability 1 in n. E.g. oneIn(3) returns false 2/3 of the
// time, and true 1/3 of the time.
function oneIn(n) {
  return (randomBits() % n) == 0;
}

// Set up the imports.
var tempRet0;
var baseImports = {
  'fuzzing-support': {
    // Logging.
    'log-i32': logValue,
    'log-i64': logValue,
    'log-f32': logValue,
    'log-f64': logValue,
    // JS cannot log v128 values (we trap on the boundary), but we must still
    // provide an import so that we do not trap during linking. (Alternatively,
    // we could avoid running JS on code with SIMD in it, but it is useful to
    // fuzz such code as much as we can.)
    'log-v128': logValue,
    'log-anyref': logRef,
    'log-funcref': logRef,
    'log-contref': logRef,
    'log-externref': logRef,

    // Throw an exception from JS.
    'throw': (which) => {
      if (!which) {
        // Throw a JS exception.
        throw new Error('js exception');
      } else {
        // Throw a wasm exception.
        throw new WebAssembly.Exception(wasmTag, [which]);
      }
    },

    // Table operations.
    'table-get': (index) => {
      return exports.table.get(toAddressType(exports.table, index));
    },
    'table-set': (index, value) => {
      exports.table.set(toAddressType(exports.table, index), value);
    },

    // Export operations.
    'call-export': /* async */ (index, flags) => {
      var rethrow = flags & 1;
      if (JSPI) {
        // TODO: Figure out why JSPI fails here.
        rethrow = 0;
      }
      if (!rethrow) {
        /* await */ callFunc(exportList[index].value);
      } else {
        tryCall(/* async */ () => /* await */ callFunc(exportList[index].value),
                rethrow);
      }
    },
    'call-export-catch': /* async */ (index) => {
      return tryCall(/* async */ () => /* await */ callFunc(exportList[index].value));
    },

    // Funcref operations.
    'call-ref': /* async */ (ref, flags) => {
      // This is a direct function reference, and just like an export, it must
      // be wrapped for JSPI.
      ref = wrapExportForJSPI(ref);
      var rethrow = flags & 1;
      if (JSPI) {
        // TODO: Figure out why JSPI fails here.
        rethrow = 0;
      }
      if (!rethrow) {
        /* await */ callFunc(ref);
      } else {
        tryCall(/* async */ () => /* await */ callFunc(ref),
                rethrow);
      }
    },
    'call-ref-catch': /* async */ (ref) => {
      ref = wrapExportForJSPI(ref);
      return tryCall(/* async */ () => /* await */ callFunc(ref));
    },

    // Sleep a given amount of ms (when JSPI) and return a given id after that.
    'sleep': (ms, id) => {
      // Also avoid sleeping even in JSPI mode, rarely, just to add variety
      // here. Only do this when we have a hash seed, that is, when we are
      // allowing randomness.
      if (!JSPI || (hasHashSeed() && oneIn(10))) {
        return id;
      }
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(id);
        }, 0); // TODO: Use the ms in some reasonable, deterministic manner.
               //       Rather than actually setTimeout on them we could manage
               //       a queue of pending sleeps manually, and order them based
               //       on the "ms" (which would not be literal ms, but just
               //       how many time units to wait).
      });
    },

    'log-branch': (id, expected, actual) => {
      console.log(`[LoggingExternalInterface log-branch ${id} ${expected} ${actual}]`);
    },
  },
  // Emscripten support.
  'env': {
    'setTempRet0': function(x) { tempRet0 = x },
    'getTempRet0': function() { return tempRet0 },
  },
};

// If Tags are available, add some.
if (typeof WebAssembly.Tag !== 'undefined') {
  // A tag for general use in the fuzzer.
  var wasmTag = baseImports['fuzzing-support']['wasmtag'] = new WebAssembly.Tag({
    'parameters': ['i32']
  });

  // The JSTag that represents a JS tag.
  baseImports['fuzzing-support']['jstag'] = WebAssembly.JSTag;

  // This allows j2wasm content to run in the fuzzer.
  baseImports['imports'] = {
    'j2wasm.ExceptionUtils.tag': new WebAssembly.Tag({
      'parameters': ['externref']
    }),
  };
}

// If JSPI is available, wrap the imports and exports.
if (JSPI) {
  for (var name of ['sleep', 'call-export', 'call-export-catch', 'call-ref',
                    'call-ref-catch']) {
    baseImports['fuzzing-support'][name] =
      new WebAssembly.Suspending(baseImports['fuzzing-support'][name]);
  }
}

function wrapExportForJSPI(value) {
  if (JSPI && typeof value === 'function') {
    value = WebAssembly.promising(value);
  }
  return value;
}

// If we are fuzzing a split module, a secondary binary will have imports for
// placeholders, whose module name defaults to 'placeholder.deferred' for the
// two-module split. Any import like
// (import "placeholder.deferred" "0" (func ..))
// will be provided by the secondary module, and must be called using an
// indirection.
if (secondBinary) {
  baseImports['placeholder.deferred'] = new Proxy({}, {
    get(target, prop, receiver) {
      // Return a function that throws. We could do an indirect call using the
      // exported table, but as we immediately link in the secondary module,
      // these stubs will not be called (they are written to the table, and the
      // secondary module overwrites them). We do need to return something so
      // the primary module links without erroring, though.
      return () => {
        throw 'proxy stub should not be called';
      }
    }
  });
}

function makeImports(module) {
  // Reflect on the imports to add necessary externref globals.
  if (WebAssembly.Module.imports === undefined) {
    // We must be running with wasm2js, in which case reference types must not
    // be enabled and there are no externref globals.
    return baseImports;
  }
  // Add missing imported immutable externref globals.
  // TODO: Support more kinds of imported globals, but this would require being
  // able to reflect more precisely on the global externtypes.
  for (var {module, name, kind} of WebAssembly.Module.imports(module)) {
    if (kind == 'global') {
      if (!baseImports[module]) {
        baseImports[module] = {};
      }
      if (!baseImports[module][name]) {
        // TODO: Use different payloads for different imports.
        baseImports[module][name] = {};
      }
    }
  }
  return baseImports;
}

// Compile and instantiate a wasm file. Receives the binary to build, and
// whether it is the second one.
function build(binary, isSecond) {
  var module = new WebAssembly.Module(binary);

  var imports = makeImports(module);

  if (isSecond) {
    assert(secondBinary);
    // Provide the primary module's exports to the secondary.
    imports['primary'] = exports;
  }

  var instance;
  try {
    instance = new WebAssembly.Instance(module, imports);
  } catch (e) {
    console.log('exception thrown: failed to instantiate module: ' + e);
    quit();
  }

  // Do not add the second instance's exports to the list, as that would be
  // noticeable by calls to call-export-*. When fuzzing wasm-split, we want the
  // original module's exports to be provided from the primary module, and it is
  // the only interface to the outside.
  if (fuzzSplit && isSecond) {
    return;
  }

  // Update the exports. Note that this adds onto |exports| and |exportList|,
  // which is intentional: if we build another wasm, or build this one more
  // than once, we want to be able to call them all, so we unify all their
  // exports. (We do trample in |exports| when keys are equal - basically this
  // is a single global namespace - but |exportList| is appended to, so we do
  // keep the ability to call anything that was ever exported.)
  //
  // Note we do not iterate on instance.exports: the order there is not
  // necessarily the order in the wasm (which is what wasm-opt --fuzz-exec uses,
  // for example), because of JS object iteration rules (numbers are considered
  // "array indexes" and appear first,
  // https://tc39.es/ecma262/#sec-ordinaryownpropertykeys).
  for (var e of WebAssembly.Module.exports(module)) {
    var key = e.name;
    var value = instance.exports[key];
    value = wrapExportForJSPI(value);
    exports[key] = value;

    if (fuzzSplit && key.startsWith('__fuzz_split_')) {
      // We are fuzzing wasm-split, and this is a new export generated by
      // wasm-split. Do not note these exports as callable from call-export*,
      // as they do not match the original pre-split module.
      continue;
    }
    exportList.push({ name: key, value: value });
  }
}

// Run the code by calling exports. The optional |ordering| parameter indicates
// howe we should order the calls to the exports: if it is not provided, we call
// them in the natural order, which allows our output to be compared to other
// executions of the wasm (e.g. from wasm-opt --fuzz-exec). If |ordering| is
// provided, it is a random seed we use to make deterministic choices on
// the order of calls.
/* async */ function callExports(ordering) {
  hashSeed = ordering;

  // Call the exports we were told, or if we were not given an explicit list,
  // call them all.
  let relevantExports = exportsToCall || exportList;

  // Build the list of call tasks to run, one for each relevant export.
  let tasks = [];
  for (let e of relevantExports) {
    let name, value;
    if (typeof e === 'string') {
      // We are given a string name to call. Look it up in the global namespace.
      name = e;
      value = exports[e];
    } else {
      // We are given an object form exportList, which has both a name and a
      // value.
      name = e.name;
      value = e.value;
    }

    if (typeof value !== 'function') {
      continue;
    }

    // A task is a name + a function to call. For an export, the function is
    // simply a call of the export.
    tasks.push({ name: name, func: /* async */ () => callFunc(value) });
  }

  // Reverse the array, so the first task is at the end, for efficient
  // popping in the common case.
  tasks.reverse();

  // Execute tasks while they remain.
  while (tasks.length) {
    let task;
    if (ordering === undefined) {
      // Use the natural order.
      task = tasks.pop();
    } else {
      // Pick a random task.
      let i = hashCombine(tasks.length) % tasks.length;
      task = tasks.splice(i, 1)[0];
    }

    // Execute the task.
    console.log(`[fuzz-exec] calling ${task.name}${task.deferred ? ' (after defer)' : ''}`);
    let result;
    try {
      result = task.func();
    } catch (e) {
      console.log('exception thrown: ' + e);
      continue;
    }

    if (JSPI) {
      // When we are changing up the order, in JSPI we can also leave some
      // promises unresolved until later, which lets us interleave them. Note we
      // never defer a task more than once, and we only defer a promise (which
      // we check for using .then).
      // TODO: Deferring more than once may make sense, by chaining promises in
      //       JS (that would not add wasm execution in the middle, but might
      //       find JS issues in principle). We could also link promises by
      //       depending on each other, ensuring certain orders of execution.
      if (ordering !== undefined && !task.deferred && result &&
          typeof result == 'object' && typeof result.then === 'function') {
        if (randomBits() & 1) {
          // Defer it for later. Reuse the existing task for simplicity.
          console.log(`(jspi: defer ${task.name})`);
          task.func = /* async */ () => {
            console.log(`(jspi: finish ${task.name})`);
            return /* await */ result;
          };
          task.deferred = true;
          tasks.push(task);
          continue;
        }
        // Otherwise, continue down.
      }

      // Await it right now.
      try {
        result = /* await */ result;
      } catch (e) {
        console.log('exception thrown: ' + e);
        continue;
      }
    }

    // Log the result.
    if (typeof result !== 'undefined') {
      console.log('[fuzz-exec] note result: ' + task.name + ' => ' + printed(result));
    }
  }
}

// Build the main wasm.
build(binary);

// Build the second wasm, if one was provided.
if (secondBinary) {
  build(secondBinary, true);
}

// Run.
callExports();
