docs: function encode(decoded, stack) {
      if (!stack) stack = [];
  
      if (decoded === undefined) return transferableUndefined;
      if (decoded === null) return null;
  
      var type = typeof(decoded);
  
      if (type === 'boolean') return decoded;
      if (type === 'string') return decoded;
      if (type === 'function') return { "!$function$!": decoded.toString() };
  
      if (type === 'number') {
        if (isNaN(decoded)) {
          return transferableNotANumber;
        } else {
          return decoded;
        }
      }
  
      if (type === 'object') {
  
        /* Proxy references */
        if (decoded.hasOwnProperty('!$proxyId$!')) {
          return { "!$proxyId$!": decoded['!$proxyId$!'] };
        }
  
        /* ArrayBuffers, views, dates, regular expressions, ... */
        if (isBufferOrView(decoded)) return encodeBufferOrView(decoded);
        if (decoded instanceof Date) return transferDate(decoded);
        if (decoded instanceof RegExp) return transferRegExp(decoded);
  
        /* Error object */
        if (decoded instanceof Error) {
          var name = decoded.name || Object.getPrototypeOf(decoded).name;
          var message = decoded.message;
          var stack = decoded.stack;
          var error = {};
          if (name) error.name = name;
          if (message) error.message = message;
          if (stack) error.stack = stack;
          return { "!$error$!": error };
        }
  
        /* Normal arrays and arrays from arguments calls */
        if ((decoded.hasOwnProperty('callee') && (typeof(decoded.length) === 'number'))
            || Array.isArray(decoded)) {
          return copy(decoded, [], stack, encode);
        }
  
        /* Other (normal) object */
        return copy(decoded, {}, stack, encode);
  
      }
  
      throw new Error("Unable to transfer " + type);
    }