// 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 === 'object') {
    // This may be one of the externref imports, in which case we can print its
    // payload.
    if (Object.hasOwn(x, 'payload')) {
      return 'externref(' + x.payload + ')';
    }
    // Or maybe this is a JS error we caught.
    if (x instanceof Error) {
      return 'jserror';
    }
    // If this is a Wasm object, we can't access its type or any of its
    // internal structure, which might have been changed by optimizations
    // anyway. It might have a configured prototype, though, and that
    // prototype may be an imported externref global we can identify by the
    // payload we gave it.
    return 'object(' + printed(Object.getPrototypeOf(x)) + ')';
  } else if (typeof x === 'function') {
    // We cannot print function names because they might have been changed by
    // optimizations.
    return 'function';
  } else {
    // A number. Print the whole thing.
    assert(typeof x === 'number');
    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]) {
        // Compute a payload from the import names. This must be kept in sync
        // with execution-results.h.
        var payload = 0;
        for (var name of [module, name]) {
          for (var c of name) {
            payload = (payload + c.charCodeAt(0)) % 251;
          }
        }
        baseImports[module][name] = { payload };
      }
    }
  }
  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();
