Given an object path and arguments, actually invokes the method and returns
the result. This method is run on the target side (i.e. not the one doing
the invoking). This method tries to figure out the return value of an object
and do the right thing, including awaiting Promises to get their values.

@param  {string} path  A path to the object to execute, in dotted
form i.e. 'document.querySelector'.
@param  {Array}  args  The arguments to pass to the method

@return {Promise<object>}      The result of evaluating path(...args)

@private
async function evalRemoteMethod(path, args) {
  let [parent, obj] = objectAndParentGivenPath(path);

  let result = obj;
  if (obj && typeof(obj) === 'function') {
    d("obj is function!");
    let res = obj.apply(parent, args);

    result = res;
    if (typeof(res) === 'object' && res && 'then' in res) {
      d("result is Promise!");
      result = await res;
    }
  }

  return result;
}