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 ObjectPropertyExpression::eval(VariableEnvironment &env) const {
  Variant obj(m_obj->eval(env));
  String name(m_name->get(env));
  env.setThis(false);
  SET_LINE;
  return obj.o_get(name);
}
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 UnsetStatement::eval(VariableEnvironment &env) const {
  if (env.isGotoing()) return;
  ENTER_STMT;
  for (std::vector<LvalExpressionPtr>::const_iterator it = m_vals.begin();
       it != m_vals.end(); ++it) {
    (*it)->unset(env);
  }
}
Example #5
0
Variant EvalFuncGetArgs::InvokeImpl(VariableEnvironment &env,
                                    CArrRef params) {
  int size = params.size();
  switch (size) {
  case 0: {
    if (ObjectData *cont = env.getContinuation()) {
      return cont->o_invoke("get_args", Array::Create());
    }
    Array res = Array::Create();
    for (ArrayIter iter(env.getParams()); !iter.end(); iter.next()) {
      res.append(iter.second());
    }
    return res;
  }
  default: return invalid_function_call("func_get_args");
  }
}
Example #6
0
Variant EvalFuncGetArg::InvokeImpl(VariableEnvironment &env,
                                   CArrRef params) {
  int size = params.size();
  switch (size) {
  case 1: {
    int n = params.rvalAt(0);
    if (ObjectData *cont = env.getContinuation()) {
      return cont->o_invoke("get_arg", CREATE_VECTOR1(n));
    }
    if (n >= 0 && n < env.getParams().size()) {
      return env.getParams().rvalAt(n);
    }
    return false;
  }
  default: return invalid_function_call("func_get_arg");
  }
}
Example #7
0
void EchoStatement::eval(VariableEnvironment &env) const {
  if (env.isGotoing()) return;
  ENTER_STMT;
  for (vector<ExpressionPtr>::const_iterator it = m_args.begin();
       it != m_args.end(); ++it) {
    echo((*it)->eval(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);
}
Example #9
0
bool CatchBlock::proc(CObjRef exn, VariableEnvironment &env) const {
  if (exn.instanceof(m_ename.c_str())) {
    if (m_body) {
      env.getVar(m_vname, m_sg) = exn;
      m_body->eval(env);
    }
    return true;
  }
  return false;
}
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;
}
Example #11
0
void JSScope::collectClosureVariablesUnderTDZ(JSScope* scope, VariableEnvironment& result)
{
    for (; scope; scope = scope->next()) {
        if (!scope->isLexicalScope() && !scope->isCatchScope())
            continue;

        if (scope->isModuleScope()) {
            AbstractModuleRecord* moduleRecord = jsCast<JSModuleEnvironment*>(scope)->moduleRecord();
            for (const auto& pair : moduleRecord->importEntries())
                result.add(pair.key);
        }

        SymbolTable* symbolTable = jsCast<JSSymbolTableObject*>(scope)->symbolTable();
        ASSERT(symbolTable->scopeType() == SymbolTable::ScopeType::LexicalScope || symbolTable->scopeType() == SymbolTable::ScopeType::CatchScope);
        ConcurrentJSLocker locker(symbolTable->m_lock);
        for (auto end = symbolTable->end(locker), iter = symbolTable->begin(locker); iter != end; ++iter)
            result.add(iter->key);
    }
}
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);
  }
}
Example #13
0
void ExprStatement::eval(VariableEnvironment &env) const {
  if (env.isGotoing()) return;

  // if m_exp hasn't set the line yet, set it, otherwise, we can skip
  // so to avoid annoying double-stay with debugger's "step" command.
  if (loc()->line1 != ThreadInfo::s_threadInfo->m_top->getLine()) {
    ENTER_STMT;
  }
  m_exp->eval(env);
}
bool TempExpressionList::evalOffsets(VariableEnvironment &env) const {
  if (!m_offsets.empty()) {
    vector<Variant> &temps = env.createTempVariables();
    temps.reserve(m_offsets.size());
    for (unsigned int i = 0; i < m_offsets.size(); i++) {
      temps.push_back(m_offsets[i]->eval(env));
    }
    return true;
  }
  return false;
}
Example #15
0
void SwitchStatement::eval(VariableEnvironment &env) const {
  bool gotoing = false;
  if (env.isGotoing()) {
    if (env.isLimitedGoto()) return;
    gotoing = true;
  }

  ENTER_STMT;
  Variant source, *srcPtr;
  if (!gotoing) {
    if (!m_simpleVar) {
      source = m_source->eval(env);
      srcPtr = &source;
    } else {
      m_source->cast<VariableExpression>()->weakLval(env, srcPtr);
    }
  }
  bool matched = false;
  vector<CaseStatementPtr>::const_iterator defaultPos = m_cases.end();

  EVAL_STMT_HANDLE_GOTO_BEGIN(restart);
  for (vector<CaseStatementPtr>::const_iterator iter = m_cases.begin();
       iter != m_cases.end(); ++iter) {
    if (!gotoing) {
      if ((*iter)->isDefault()) {
        defaultPos = iter;
      } else if (!matched && (*iter)->match(env, *srcPtr)) {
        matched = true;
      }
    }
    if (gotoing || matched) {
      EVAL_STMT_HANDLE_BREAK_CONT(*iter, env);
    }
  }
  if (!gotoing && !matched && defaultPos != m_cases.end()) {
    for (; defaultPos != m_cases.end(); ++defaultPos) {
      EVAL_STMT_HANDLE_BREAK_CONT(*defaultPos, env);
    }
  }
  EVAL_STMT_HANDLE_GOTO_END(restart);
}
Example #16
0
void WhileStatement::eval(VariableEnvironment &env) const {
  DECLARE_THREAD_INFO;

  if (env.isGotoing()) {
    if (env.isLimitedGoto()) return;
    goto body;
  }
  ENTER_STMT;
  LOOP_COUNTER(1);

  begin:
  if (m_cond->eval(env)) {
    body:
    LOOP_COUNTER_CHECK_INFO(1);
    EVAL_STMT_HANDLE_GOTO_BEGIN(restart);
    if (m_body) EVAL_STMT_HANDLE_GOTO(m_body, env);
    EVAL_STMT_HANDLE_GOTO_END(restart);
    goto begin;
  }
  end:;
}
Variant ClosureExpression::eval(VariableEnvironment &env) const {
  m_func->eval(env);
  Array vars;
  for (unsigned int i = 0; i < m_vars.size(); i++) {
    Parameter *param = m_vars[i].get();
    String name = param->getName();
    SuperGlobal sg;
    if (!param->getSuperGlobal(sg)) {
      sg = VariableIndex::isSuperGlobal(name);
    }
    if (param->isRef()) {
      vars.append(ref(env.getVar(name, sg)));
    } else {
      vars.append(env.getVar(name, sg));
    }
  }

  // need to get at low level constructor
  return Object(NEWOBJ(c_GeneratorClosure)(
                m_func->getClosureCallInfo(), m_func.get(), vars));
}
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;
}
Example #21
0
void TryStatement::eval(VariableEnvironment &env) const {
  if (env.isGotoing()) return;
  ENTER_STMT;
  try {
    EVAL_STMT_HANDLE_GOTO_BEGIN(restart1);
    m_body->eval(env);
    EVAL_STMT_HANDLE_GOTO_END(restart1);
  } catch (Object e) {
    for (vector<CatchBlockPtr>::const_iterator it = m_catches.begin();
         it != m_catches.end(); ++it) {
      if ((*it)->match(e)) {
        if ((*it)->body()) {
          env.get(String((*it)->vname())) = e;
          EVAL_STMT_HANDLE_GOTO_BEGIN(restart2);
          EVAL_STMT((*it)->body(), env);
          EVAL_STMT_HANDLE_GOTO_END(restart2);
        }
        return;
      }
    }
    throw e;
  }
}
Example #22
0
Variant EvalFuncGetArgs::InvokeImpl(VariableEnvironment &env,
                                    CArrRef params) {
  int size = params.size();
  switch (size) {
  case 0: {
    Array res = Array::Create();
    for (ArrayIter iter(env.getParams()); !iter.end(); iter.next()) {
      res.append(iter.second());
    }
    return res;
  }
  default: throw InvalidFunctionCallException("func_get_args");
  }
}
Example #23
0
void Parameter::bind(VariableEnvironment &env, CVarRef val,
                     bool ref /* = false */) const {
  if (m_kind != KindOfNull) {
    DataType otype = val.getType();
    if (!(m_nullDefault && otype == KindOfNull ||
          otype == m_kind &&
          (m_kind != KindOfObject ||
           m_kind == KindOfObject &&
           val.toObject().instanceof(m_type.c_str())))) {
      throw_unexpected_argument_type(m_argNum, m_fnName, m_type.c_str(), val);
    }
  }
  if (ref) val.setContagious();
  env.getIdx(m_idx) = val;
}
Example #24
0
void TryStatement::eval(VariableEnvironment &env) const {
  ENTER_STMT;
  try {
    m_body->eval(env);
  } catch (Object e) {
    for (vector<CatchBlockPtr>::const_iterator it = m_catches.begin();
         it != m_catches.end(); ++it) {
      if ((*it)->match(e)) {
        if ((*it)->body()) {
          env.get((*it)->vname()) = e;
          EVAL_STMT((*it)->body(), env);
        }
        return;
      }
    }
    throw e;
  }
}
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;
}
Example #26
0
void MethodStatement::eval(VariableEnvironment &env) const {
  if (env.isGotoing()) return;
  ENTER_STMT;
  // register with reflection, invoke, etc.
}
Example #27
0
Variant EvalGetDefinedVars::InvokeImpl(VariableEnvironment &env,
                                       CArrRef params) {
  return env.getDefinedVariables();
}
Example #28
0
Variant EvalFuncNumArgs::InvokeImpl(VariableEnvironment &env,
                                    CArrRef params) {
  int size = params.size();
  if (size != 0) throw InvalidFunctionCallException("func_num_args");
  return env.getParams().size();
}
Variant ThisStringPropertyExpression::evalExist(VariableEnvironment &env)
  const {
  SET_LINE;
  return env.currentObject().o_get(m_name, false);
}
void VariableExpression::unset(VariableEnvironment &env) const {
    String name(m_name->get(env));
    env.unset(name, m_name->hash());
}