// 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) | 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) + ']');
}

// 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 imports = {
  '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,

    // 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 = imports['fuzzing-support']['wasmtag'] = new WebAssembly.Tag({
    'parameters': ['i32']
  });

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

  // This allows j2wasm content to run in the fuzzer.
  imports['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']) {
    imports['fuzzing-support'][name] =
      new WebAssembly.Suspending(imports['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) {
  imports['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';
      }
    }
  });
}

// Compile and instantiate a wasm file. Receives the binary to build, and
// whether it is the second one.
function build(binary, isSecond) {
  if (isSecond) {
    assert(secondBinary);
    // Provide the primary module's exports to the secondary.
    imports['primary'] = exports;
  }

  var module = new WebAssembly.Module(binary);

  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();
