Ejemplo n.º 1
0
bool ThisExpression::exist(VariableEnvironment &env, int op) const {
  if (op == T_ISSET) {
    return HPHP::isset(env.currentObject());
  }
  ASSERT(op == T_EMPTY);
  return HPHP::empty(env.currentObject());
}
Ejemplo n.º 2
0
Variant UnaryOpExpression::eval(VariableEnvironment &env) const {
  if (m_op == '@') {
    Silencer s;
    s.enable();
    return m_exp->eval(env);
  } else if (m_op == T_ISSET || m_op == T_EMPTY) {
    return m_exp->exist(env, m_op);
  }

  Variant exp(m_exp ? m_exp->eval(env) : null_variant);
  SET_LINE;
  switch (m_op) {
  case T_CLONE:       return f_clone(exp);
  case '+':           return +exp;
  case '-':           return negate(exp);
  case '!':           return !exp;
  case '~':           return ~exp;
  case T_INT_CAST:    return toInt64(exp);
  case T_DOUBLE_CAST: return toDouble(exp);
  case T_STRING_CAST: return toString(exp);
  case T_ARRAY_CAST:  return toArray(exp);
  case T_OBJECT_CAST: return toObject(exp);
  case T_BOOL_CAST:   return toBoolean(exp);
  case T_UNSET_CAST:  return unset(exp);
  case T_EXIT:        return f_exit(exp);
  case T_PRINT:       return print(exp.toString());
  case T_EVAL:        return HPHP::eval(&env, env.currentObject(), exp);
  default:
    ASSERT(false);
    return Variant();
  }
}
Variant ObjectMethodExpression::eval(VariableEnvironment &env) const {
  String name(m_name->get(env));
  Variant obj(m_obj->eval(env));
  if (!obj.is(KindOfObject)) {
    raise_error("Call to a member function %s() on a non-object",
                name.c_str());
  }
  EvalFrameInjection::EvalStaticClassNameHelper helper(obj.toObject());

  Variant cobj(env.currentObject());
  const MethodStatement *ms = NULL;
  if (cobj.is(KindOfObject) && obj.getObjectData() == cobj.getObjectData()) {
    // Have to try current class first for private method
    const ClassStatement *cls = env.currentClassStatement();
    if (cls) {
      const MethodStatement *ccms = cls->findMethod(name.c_str());
      if (ccms && ccms->getModifiers() & ClassStatement::Private) {
        ms = ccms;
      }
    }
  }
  if (!ms) {
    ms = obj.getObjectData()->getMethodStatement(name.data());
  }
  SET_LINE;
  if (ms) {
    return ref(ms->invokeInstanceDirect(toObject(obj), env, this));
  }
  return ref(obj.getObjectData()->o_invoke_from_eval(name.data(), env, this,
                                                     m_name->hash(), true));
}
Ejemplo n.º 4
0
Variant StaticMethodExpression::eval(VariableEnvironment &env) const {
    SET_LINE;
    // Static method expressions can be object method expressions inside
    // of a method when an object is available and the object's class inherits.
    // Super slow.
    String name(m_name->get(env));
    Object co(env.currentObject());
    bool withinClass = !co.isNull() && co->o_instanceof(m_cname.data());
    bool foundClass;
    const MethodStatement *ms = RequestEvalState::findMethod(m_cname.data(),
                                name.data(),
                                foundClass);
    if (withinClass) {
        if (m_construct && !ms) {
            // In a class method doing __construct will go to the name constructor
            ms = RequestEvalState::findMethod(m_cname.data(),
                                              m_cname.data(),
                                              foundClass);
        }
        if (ms) {
            return ref(ms->invokeInstanceDirect(co, env, this));
        }
        return ref(co->o_invoke_ex(m_cname.data(), name.data(), getParams(env),
                                   m_name->hashLwr()));

    }
    if (ms) {
        return ref(ms->invokeStaticDirect(m_cname.data(), env, this));
    }
    return ref(invoke_static_method(m_cname.data(), name.data(), getParams(env)));
}
void ThisStringPropertyExpression::unset(VariableEnvironment &env) const {
  Variant *obj = &env.currentObject();

  if (!obj->is(KindOfObject)) {
    SET_LINE_VOID;
    raise_error("Using $this when not in an object context");
  }
  obj->o_unset(m_name);
}
bool ThisStringPropertyExpression::exist(VariableEnvironment &env, int op)
  const {
  Variant *obj = &env.currentObject();
  SET_LINE;
  if (op == T_ISSET) {
    return obj->o_isset(m_name);
  } else {
    return obj->o_empty(m_name);
  }
}
Variant ThisStringPropertyExpression::setRef(VariableEnvironment &env,
  CVarRef val) const {
  Variant &lv = env.currentObject();
  SET_LINE;
  if (!lv.is(KindOfObject)) {
    raise_error("Using $this when not in an object context");
  }
  lv.o_setRef(m_name, val);
  return val;
}
Variant ThisStringPropertyExpression::eval(VariableEnvironment &env) const {
  const Variant *op = &env.currentObject();
  SET_LINE;
  if (!g_context->getDebuggerBypassCheck()) {
    return op->o_get(m_name);
  }
  Variant v = op->o_get(m_name, false);
  if (!v.isNull()) return v;
  CStrRef context = op->isObject() ?
                    op->getObjectData()->o_getClassName() :
                    null_string;
  return op->o_get(m_name, false, context);
}
Variant StaticMethodExpression::eval(VariableEnvironment &env) const {
  SET_LINE;
  // Static method expressions can be object method expressions inside
  // of a method when an object is available and the object's class inherits.
  // Super slow.
  String cname = m_cname->get(env);
  bool sp = m_cname->isSp();
  String name(m_name->get(env));
  Variant &vco = env.currentObject();
  Object co;
  if (!vco.isNull()) co = vco.toObject();
  bool withinClass = !co.isNull() && co->o_instanceof(cname.data());
  bool foundClass;
  const MethodStatement *ms = RequestEvalState::findMethod(cname.data(),
                                                           name.data(),
                                                           foundClass);
  if (withinClass) {
    if (m_construct) {
      String name = cname;
      while (true) {
        ClassEvalState *ces = RequestEvalState::findClassState(name.data());
        if (!ces) {
          // possibly built in
          cname = name;
          break;
        }
        // Ugly but needed to populate the method table for the parent
        ces->initializeInstance();
        ms = ces->getConstructor();
        if (ms) break;
        name = ces->getClass()->parent().c_str();
        if (name.empty()) break;
      }
    }
    if (!ms) {
      Array params = getParams(env);
      EvalFrameInjection::EvalStaticClassNameHelper helper(cname, sp);
      return ref(co->o_invoke_ex(cname, name, params));
    } else if (!(ms->getModifiers() & ClassStatement::Static)) {
      EvalFrameInjection::EvalStaticClassNameHelper helper(cname, sp);
      return ref(ms->invokeInstanceDirect(co, env, this));
    }
  }
  if (ms) {
    EvalFrameInjection::EvalStaticClassNameHelper helper(cname, sp);
    return ref(ms->invokeStaticDirect(cname.data(), env, this));
  }
  Array params = getParams(env);
  EvalFrameInjection::EvalStaticClassNameHelper helper(cname, sp);
  return ref(invoke_static_method(cname.data(), name.data(), params));
}
bool ThisStringPropertyExpression::weakLval(VariableEnvironment &env,
                                        Variant* &v) const {
  Variant *obj = &env.currentObject();

  if (!obj->is(KindOfObject)) {
    SET_LINE;
    raise_error("Using $this when not in an object context");
    return false;
  }
  if (!SET_LINE_EXPR) return false;
  Variant tmp;
  v = &obj->o_unsetLval(m_name, tmp);
  return v != &tmp;
}
Variant ThisStringPropertyExpression::setOp(VariableEnvironment &env,
  int op, CVarRef rhs) const {
  Variant *vobj = &env.currentObject();

  if (!vobj->is(KindOfObject)) {
    SET_LINE;
    raise_error("Using $this when not in an object context");
  }
  SET_LINE;
  switch (op) {
    case T_PLUS_EQUAL:
      return vobj->o_assign_op<Variant, T_PLUS_EQUAL>(m_name, rhs);
    case T_MINUS_EQUAL:
      return vobj->o_assign_op<Variant, T_MINUS_EQUAL>(m_name, rhs);
    case T_MUL_EQUAL:
      return vobj->o_assign_op<Variant, T_MUL_EQUAL>(m_name, rhs);
    case T_DIV_EQUAL:
      return vobj->o_assign_op<Variant, T_DIV_EQUAL>(m_name, rhs);
    case T_CONCAT_EQUAL:
      return vobj->o_assign_op<Variant, T_CONCAT_EQUAL>(m_name, rhs);
    case T_MOD_EQUAL:
      return vobj->o_assign_op<Variant, T_MOD_EQUAL>(m_name, rhs);
    case T_AND_EQUAL:
      return vobj->o_assign_op<Variant, T_AND_EQUAL>(m_name, rhs);
    case T_OR_EQUAL:
      return vobj->o_assign_op<Variant, T_OR_EQUAL>(m_name, rhs);
    case T_XOR_EQUAL:
      return vobj->o_assign_op<Variant, T_XOR_EQUAL>(m_name, rhs);
    case T_SL_EQUAL:
      return vobj->o_assign_op<Variant, T_SL_EQUAL>(m_name, rhs);
    case T_SR_EQUAL:
      return vobj->o_assign_op<Variant, T_SR_EQUAL>(m_name, rhs);
    case T_INC:
      return vobj->o_assign_op<Variant, T_INC>(m_name, rhs);
    case T_DEC:
      return vobj->o_assign_op<Variant, T_DEC>(m_name, rhs);
    default:
      ASSERT(false);
  }
  return rhs;
}
Variant ThisStringPropertyExpression::evalExist(VariableEnvironment &env)
  const {
  SET_LINE;
  return env.currentObject().o_get(m_name, false);
}
Ejemplo n.º 13
0
Variant ObjectMethodExpression::eval(VariableEnvironment &env) const {
    String name(m_name->get(env));
    Variant obj(m_obj->eval(env));
    if (!obj.is(KindOfObject)) {
        raise_error("Call to a member function %s() on a non-object",
                    name.c_str());
    }
#ifdef ENABLE_LATE_STATIC_BINDING
    EvalFrameInjection::EvalStaticClassNameHelper helper(obj.toObject());
#endif
    Variant cobj(env.currentObject());
    const MethodStatement *ms = NULL;
    if (cobj.is(KindOfObject) && obj.getObjectData() == cobj.getObjectData()) {
        // Have to try current class first for private method
        const ClassStatement *cls = env.currentClassStatement();
        if (cls) {
            const MethodStatement *ccms = cls->findMethod(name.c_str());
            if (ccms && ccms->getModifiers() & ClassStatement::Private) {
                ms = ccms;
            }
        }
    }
    if (!ms) {
        ms = obj.getObjectData()->getMethodStatement(name.data());
    }
    SET_LINE;
    if (ms) {
        return strongBind(ms->invokeInstanceDirect(toObject(obj), env, this));
    }

    // Handle builtins
    MethodCallPackage mcp1;
    mcp1.methodCall(obj, name, -1);
    const CallInfo* ci = mcp1.ci;
    // If the lookup failed methodCall() must throw an exception,
    // so if we reach here ci must not be NULL
    ASSERT(ci);
    unsigned int count = m_params.size();
    if (count <= 6) {
        CVarRef a0 = (count > 0) ? evalParam(env, ci, 0) : null;
        CVarRef a1 = (count > 1) ? evalParam(env, ci, 1) : null;
        CVarRef a2 = (count > 2) ? evalParam(env, ci, 2) : null;
        CVarRef a3 = (count > 3) ? evalParam(env, ci, 3) : null;
        CVarRef a4 = (count > 4) ? evalParam(env, ci, 4) : null;
        CVarRef a5 = (count > 5) ? evalParam(env, ci, 5) : null;
        return
            strongBind((ci->getMethFewArgs())(mcp1, count, a0, a1, a2, a3, a4, a5));
    }
    if (RuntimeOption::UseArgArray) {
        ArgArray *args = prepareArgArray(env, ci, count);
        return strongBind((ci->getMeth())(mcp1, args));
    }
    ArrayInit ai(count);
    for (unsigned int i = 0; i < count; ++i) {
        if (ci->mustBeRef(i)) {
            ai.setRef(m_params[i]->refval(env));
        } else if (ci->isRef(i)) {
            ai.setRef(m_params[i]->refval(env, 0));
        } else {
            ai.set(m_params[i]->eval(env));
        }
    }
    return strongBind((ci->getMeth())(mcp1, Array(ai.create())));
}
Ejemplo n.º 14
0
Variant ThisExpression::eval(VariableEnvironment &env) const {
  return env.currentObject();
}
Ejemplo n.º 15
0
Variant StaticMethodExpression::eval(VariableEnvironment &env) const {
  SET_LINE;
  // Static method expressions can be object method expressions inside
  // of a method when an object is available and the object's class inherits.
  // Super slow.
  String cname = m_cname->get(env);
  bool sp = m_cname->isSp();
  String name(m_name->get(env));
  Variant &vco = env.currentObject();
  Object co;
  if (!vco.isNull()) co = vco.toObject();
  bool withinClass = !co.isNull() && co->o_instanceof(cname.data());
  bool foundClass;
  const MethodStatement *ms = RequestEvalState::findMethod(cname.data(),
                                                           name.data(),
                                                           foundClass);
  if (withinClass) {
    if (m_construct) {
      String name = cname;
      while (true) {
        ClassEvalState *ces = RequestEvalState::findClassState(name.data());
        if (!ces) {
          // possibly built in
          cname = name;
          break;
        }
        // Ugly but needed to populate the method table for the parent
        ces->initializeInstance();
        ms = ces->getConstructor();
        if (ms) break;
        name = ces->getClass()->parent().c_str();
        if (name.empty()) break;
      }
    }
    if (!ms) {
      Array params = getParams(env);
      EvalFrameInjection::EvalStaticClassNameHelper helper(cname, sp);
      return strongBind(co->o_invoke_ex(cname, name, params));
    } else if (!(ms->getModifiers() & ClassStatement::Static)) {
      EvalFrameInjection::EvalStaticClassNameHelper helper(cname, sp);
      return strongBind(ms->invokeInstanceDirect(co, env, this));
    }
  }
  if (ms) {
    return strongBind(ms->invokeStaticDirect(cname, env, this, sp));
  }

  // Handle builtins
  MethodCallPackage mcp1;
  mcp1.dynamicNamedCall(cname, name, -1);
  const CallInfo* cit1 = mcp1.ci;
  // If the lookup failed dynamicNamedCall() must throw an exception,
  // so if we reach here cit1 must not be NULL
  ASSERT(cit1);
  ArrayInit ai(m_params.size(), true);
  for (unsigned int i = 0; i < m_params.size(); ++i) {
    if (cit1->mustBeRef(i)) {
      ai.setRef(m_params[i]->refval(env));
    } else if (cit1->isRef(i)) {
      ai.setRef(m_params[i]->refval(env, 0));
    } else {
      ai.set(m_params[i]->eval(env));
    }
  }
  return strongBind((cit1->getMeth())(mcp1, Array(ai.create())));
}