int len = _defaultExprs.length + (_hasEnv ? 1 : 0) + (_hasRestArgs ? 1 : 0);  Object []values = new Object[len];  int k = 0;  if (_hasEnv) values[k++] = env;  for (int i = 0; i < _marshallArgs.length; i++) { Expr expr;  if (i < exprs.length && exprs[i] != null) expr = exprs[i]; else { expr = _defaultExprs[i];  if (expr == null) expr = new DefaultExpr(getLocation()); }  values[k] = _marshallArgs[i].marshall(env, expr, _paramTypes[k]);  k++; }  if (_hasRestArgs) { Value []rest;  int restLen = exprs.length - _marshallArgs.length;  if (restLen <= 0) rest = NULL_VALUES; else { rest = new Value[restLen];   for (int i = _marshallArgs.length; i < exprs.length; i++) { if (_isRestReference) rest[i - _marshallArgs.length] = exprs[i].evalRef(env); else rest[i - _marshallArgs.length] = exprs[i].eval(env); } }  values[values.length - 1] = rest; }  try { Object result = invoke(obj, values);  return _unmarshallReturn.unmarshall(env, result); } catch (InvocationTargetException e) { if (e.getCause() != null) throw e.getCause(); else throw e; }
return eval(env, env.getThis(), value);
  public Value eval(Env env, Object obj, Expr []exprs)    throws Throwable  {    int len = _defaultExprs.length + (_hasEnv ? 1 : 0) + (_hasRestArgs ? 1 : 0);    Object []values = new Object[len];    int k = 0;    if (_hasEnv)      values[k++] = env;    for (int i = 0; i < _marshallArgs.length; i++) {      Expr expr;      if (i < exprs.length && exprs[i] != null)        expr = exprs[i];      else {        expr = _defaultExprs[i];        if (expr == null)          expr = new DefaultExpr(getLocation());      }      values[k] = _marshallArgs[i].marshall(env, expr, _paramTypes[k]);      k++;    }    if (_hasRestArgs) {      Value []rest;      int restLen = exprs.length - _marshallArgs.length;      if (restLen <= 0)        rest = NULL_VALUES;      else {        rest = new Value[restLen];        for (int i = _marshallArgs.length; i < exprs.length; i++) {          if (_isRestReference)            rest[i - _marshallArgs.length] = exprs[i].evalRef(env);          else            rest[i - _marshallArgs.length] = exprs[i].eval(env);        }      }      values[values.length - 1] = rest;    }    try {      Object result = invoke(obj, values);      return _unmarshallReturn.unmarshall(env, result);    } catch (InvocationTargetException e) {      if (e.getCause() != null)        throw e.getCause();      else        throw e;    }  }