Exemple #1
0
// TODO zPrepArgs needs to be updated so take care of
// boxing varargs
void zPrepArgs(ActRec* ar) {
  // If you call a function with too few params, zend_parse_parameters will
  // reject it, but we don't want this function boxing random slots from the
  // stack
  int32_t numArgs = std::min(ar->numArgs(), ar->m_func->numParams());
  TypedValue* args = (TypedValue*)ar - 1;
  for (int32_t i = 0; i < numArgs; ++i) {
    TypedValue* arg = args-i;
    zBoxAndProxy(arg);
  }
}
Exemple #2
0
void * ProxyArray::elementToData(TypedValue * tv) const {
  if (!tv) {
    return nullptr;
  }
  if (hasZvalValues()) {
    zBoxAndProxy(tv);
    return (void*)(&tv->m_data.pref);
  } else {
    always_assert(tv->m_type == KindOfResource);
    ZendCustomElement * elt = dynamic_cast<ZendCustomElement*>(tv->m_data.pres);
    always_assert(elt);
    return elt->data();
  }
}
Exemple #3
0
zval* ZendExecutionStack::getArg(int i) {
  auto& stack = getStack();
  auto& entry = stack.m_stack.back();
  switch (entry.mode) {
    case ZendStackMode::HHVM_STACK: {
      ActRec* ar = (ActRec*)entry.value;
      const int numNonVaradic = ar->m_func->numNonVariadicParams();
      TypedValue* arg;
      if (i < numNonVaradic) {
        arg = (TypedValue*)ar - i - 1;
      } else if (i < ar->numArgs()) {
        arg = ar->getExtraArg(i - numNonVaradic);
      } else {
        if (!stack.m_nullArg) {
          stack.m_nullArg = RefData::Make(make_tv<KindOfNull>());
        }
        return stack.m_nullArg;
      }

      zBoxAndProxy(arg);
      return arg->m_data.pref;
    }

    case ZendStackMode::SIDE_STACK: {
      // Zend puts the number of args as the last thing on the stack
      int numargs = uintptr_t(entry.value);
      assert(numargs < 4096);
      assert(i < numargs);
      zval* zv =
        (zval*) stack.m_stack[stack.m_stack.size() - 1 - numargs + i].value;
      zv->assertValid();
      return zv;
    }
  }
  not_reached();
  return nullptr;
}