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

// wasm2js does not define RuntimeError, so use that to check for it. wasm2js
// overrides the entire WebAssembly object with a polyfill, so we know exactly
// what it contains, and we need to handle some things differently below.
var wasm2js = !WebAssembly.RuntimeError;

// 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.
    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 from exportList, which has both a name and a
      // value.
      name = e.name;
      value = e.value;
    }

    // Check for a global. Note we must be careful in wasm2js mode, where we
    // can't do instanceof here (the wasm polyfill there doesn't have such
    // things). In wasm2js we strip global exports to avoid needing to handle
    // them here (using stub-unsupported-js).
    if (!wasm2js && (value instanceof WebAssembly.Global)) {
      // We can log a global value and do other operations to check for bugs.
      // First, do some operations on the Global wrapper itself.
      JSON.stringify(value);
      value.foobar;

      // Log it at the right time later using a lambda. Note that we can't just
      // capture |value| for the lambda, as the loop modifies it.
      (() => {
        var global = value;
        value = () => {
          // Time to log. Look at the exported value itself, not the global
          // wrapper.
          let actualValue;
          try {
            actualValue = global.value;
          } catch (e) {
            if (e.message.startsWith('get WebAssembly.Global.value')) {
              // Just log a string instead of a value we cannot access from JS,
              // like an exnref. Note we don't need matching code on the C++
              // side in execution-results.h because illegal exports are pruned
              // anyhow if we are going to compare execution in JS to C++.
              actualValue = '<illegal value>';
            } else {
              throw e;
            }
          }
          if (typeof actualValue === 'object') {
            // logRef can do a little more than logValue, so use it when possible.
            logRef(actualValue);
          } else {
            logValue(actualValue);
          }
        };
      })();
    }

    if (typeof value !== 'function') {
      // Nothing we can call.
      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] export ${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();
