Beispiel #1
0
static void walk_func(VRefParam value, CVarRef key, CVarRef userdata,
                      const void *data) {
  CallCtx* ctx = (CallCtx*)data;
  Variant sink;
  TypedValue args[3] = { *value->asRef(), *key.asCell(), *userdata.asCell() };
  g_vmContext->invokeFuncFew(sink.asTypedValue(), *ctx, 3, args);
}
Beispiel #2
0
static Variant reduce_func(CVarRef result, CVarRef operand, const void *data) {
  CallCtx* ctx = (CallCtx*)data;
  Variant ret;
  TypedValue args[2] = { *result.asCell(), *operand.asCell() };
  g_vmContext->invokeFuncFew(ret.asTypedValue(), *ctx, 2, args);
  return ret;
}
Beispiel #3
0
bool UnaryOpExpression::preCompute(CVarRef value, Variant &result) {
  bool ret = true;
  try {
    g_context->setThrowAllErrors(true);
    switch(m_op) {
      case '!':
        result = (!toBoolean(value)); break;
      case '+':
        cellSet(cellAdd(make_tv<KindOfInt64>(0), *value.asCell()),
                *result.asCell());
        break;
      case '-':
        cellSet(cellSub(make_tv<KindOfInt64>(0), *value.asCell()),
                *result.asCell());
        break;
      case '~':
        tvSet(*value.asCell(), *result.asTypedValue());
        cellBitNot(*result.asCell());
        break;
      case '@':
        result = value;
        break;
      case T_INT_CAST:
        result = value.toInt64();
        break;
      case T_DOUBLE_CAST:
        result = toDouble(value);
        break;
      case T_STRING_CAST:
        result = toString(value);
        break;
      case T_BOOL_CAST:
        result = toBoolean(value);
        break;
      case T_EMPTY:
        result = !toBoolean(value);
        break;
      case T_ISSET:
        result = is_not_null(value);
        break;
      case T_INC:
      case T_DEC:
        assert(false);
      default:
        ret = false;
        break;
    }
  } catch (...) {
    ret = false;
  }
  g_context->setThrowAllErrors(false);
  return ret;
}
Beispiel #4
0
bool f_define(const String& name, CVarRef value,
              bool case_insensitive /* = false */) {
  if (case_insensitive) {
    raise_warning(Strings::CONSTANTS_CASE_SENSITIVE);
  }
  return Unit::defCns(name.get(), value.asCell());
}
Beispiel #5
0
bool same(CVarRef v1, int64_t v2) {
  auto const cell = v1.asCell();
  switch (cell->m_type) {
  case KindOfInt64:
    return v2 == cell->m_data.num;
  default:
    break;
  }
  return false;
}
Beispiel #6
0
Variant f_array_combine(CVarRef keys, CVarRef values) {
  const auto& cell_keys = *keys.asCell();
  const auto& cell_values = *values.asCell();
  if (UNLIKELY(!isContainer(cell_keys) || !isContainer(cell_values))) {
    raise_warning("Invalid operand type was used: array_combine expects "
                  "arrays or collections");
    return uninit_null();
  }
  if (UNLIKELY(getContainerSize(cell_keys) != getContainerSize(cell_values))) {
    raise_warning("array_combine(): Both parameters should have an equal "
                  "number of elements");
    return false;
  }
  Array ret = ArrayData::Create();
  for (ArrayIter iter1(cell_keys), iter2(cell_values);
       iter1; ++iter1, ++iter2) {
    ret.lvalAt(iter1.secondRefPlus()).setWithRef(iter2.secondRefPlus());
  }
  return ret;
}
Beispiel #7
0
HOT_FUNC
bool f_array_key_exists(CVarRef key, CVarRef search) {
  const ArrayData *ad;

  auto const searchCell = search.asCell();
  if (LIKELY(searchCell->m_type == KindOfArray)) {
    ad = searchCell->m_data.parr;
  } else if (searchCell->m_type == KindOfObject) {
    ObjectData* obj = searchCell->m_data.pobj;
    if (obj->isCollection()) {
      return collectionOffsetContains(obj, key);
    }
    return f_array_key_exists(key, toArray(search));
  } else {
    throw_bad_type_exception("array_key_exists expects an array or an object; "
                             "false returned.");
    return false;
  }

  auto const cell = key.asCell();
  switch (cell->m_type) {
  case KindOfString:
  case KindOfStaticString: {
    int64_t n = 0;
    StringData *sd = cell->m_data.pstr;
    if (sd->isStrictlyInteger(n)) {
      return ad->exists(n);
    }
    return ad->exists(StrNR(sd));
  }
  case KindOfInt64:
    return ad->exists(cell->m_data.num);
  case KindOfUninit:
  case KindOfNull:
    return ad->exists(empty_string);
  default:
    break;
  }
  raise_warning("Array key should be either a string or an integer");
  return false;
}
Beispiel #8
0
void objOffsetUnset(ObjectData* base, CVarRef offset) {
  objArrayAccess(base);
  static StringData* sd__offsetUnset
    = makeStaticString("offsetUnset");
  assert(!base->isCollection());
  const Func* method = base->methodNamed(sd__offsetUnset);
  assert(method != nullptr);
  TypedValue tv;
  tvWriteUninit(&tv);
  g_vmContext->invokeFuncFew(&tv, method, base, nullptr, 1, offset.asCell());
  tvRefcountedDecRef(&tv);
}
Beispiel #9
0
Variant f_array_values(CVarRef input) {
  const auto& cell_input = *input.asCell();
  if (!isContainer(cell_input)) {
    raise_warning("array_values() expects parameter 1 to be an array "
                  "or collection");
    return uninit_null();
  }
  PackedArrayInit ai(getContainerSize(cell_input));
  for (ArrayIter iter(cell_input); iter; ++iter) {
    ai.appendWithRef(iter.secondRefPlus());
  }
  return ai.toArray();
}
Beispiel #10
0
static bool objOffsetExists(ObjectData* base, CVarRef offset) {
  objArrayAccess(base);
  TypedValue tvResult;
  tvWriteUninit(&tvResult);
  static StringData* sd__offsetExists
    = makeStaticString("offsetExists");
  assert(!base->isCollection());
  const Func* method = base->methodNamed(sd__offsetExists);
  assert(method != nullptr);
  g_vmContext->invokeFuncFew(&tvResult, method, base, nullptr, 1,
                             offset.asCell());
  tvCastToBooleanInPlace(&tvResult);
  return bool(tvResult.m_data.num);
}
Beispiel #11
0
void StringBuffer::append(CVarRef v) {
  auto const cell = v.asCell();
  switch (cell->m_type) {
  case KindOfStaticString:
  case KindOfString:
    append(cell->m_data.pstr);
    break;
  case KindOfInt64:
    append(cell->m_data.num);
    break;
  default:
    append(v.toString());
  }
}
Beispiel #12
0
void objOffsetSet(ObjectData* base, CVarRef offset, TypedValue* val,
                  bool validate /* = true */) {
  if (validate) {
    objArrayAccess(base);
  }
  static StringData* sd__offsetSet = makeStaticString("offsetSet");
  assert(!base->isCollection());
  const Func* method = base->methodNamed(sd__offsetSet);
  assert(method != nullptr);
  TypedValue tvResult;
  tvWriteUninit(&tvResult);
  TypedValue args[2] = { *offset.asCell(), *tvToCell(val) };
  g_vmContext->invokeFuncFew(&tvResult, method, base, nullptr, 2, args);
  tvRefcountedDecRef(&tvResult);
}
Beispiel #13
0
Variant f_array_keys(CVarRef input, CVarRef search_value /* = null_variant */,
                     bool strict /* = false */) {
  const auto& cell_input = *input.asCell();
  if (UNLIKELY(!isContainer(cell_input))) {
    goto warn;
  }
  {
    // We treat Sets differently. For Sets, we pretend the values are
    // also the keys (similar to how Set::toArray() behaves).
    bool isSetType =
      cell_input.m_type == KindOfObject &&
      cell_input.m_data.pobj->getCollectionType() == Collection::SetType;
    if (UNLIKELY(isSetType)) {
      return arrayKeysSetHelper(cell_input, search_value, strict);
    }
    ArrayIter iter(cell_input);
    if (LIKELY(!search_value.isInitialized())) {
      PackedArrayInit ai(getContainerSize(cell_input));
      for (; iter; ++iter) {
        ai.append(iter.first());
      }
      return ai.toArray();
    }

    Array ai = Array::attach(HphpArray::MakeReserve(0));
    for (; iter; ++iter) {
      if ((strict && HPHP::same(iter.secondRefPlus(), search_value)) ||
          (!strict && HPHP::equal(iter.secondRefPlus(), search_value))) {
        ai.append(iter.first());
      }
    }
    return ai;
  }
warn:
  raise_warning("array_keys() expects parameter 1 to be an array "
                "or collection");
  return uninit_null();
}
Beispiel #14
0
bool f_is_callable(CVarRef v, bool syntax /* = false */,
                   VRefParam name /* = null */) {
  bool ret = true;
  if (LIKELY(!syntax)) {
    CallerFrame cf;
    ObjectData* obj = NULL;
    HPHP::Class* cls = NULL;
    StringData* invName = NULL;
    const HPHP::Func* f = vm_decode_function(v, cf(), false, obj, cls,
                                                 invName, false);
    if (f == NULL) {
      ret = false;
    }
    if (invName != NULL) {
      decRefStr(invName);
    }
    if (!name.isReferenced()) return ret;
  }

  auto const tv_func = v.asCell();
  if (IS_STRING_TYPE(tv_func->m_type)) {
    if (name.isReferenced()) name = tv_func->m_data.pstr;
    return ret;
  }

  if (tv_func->m_type == KindOfArray) {
    CArrRef arr = tv_func->m_data.parr;
    CVarRef clsname = arr.rvalAtRef(int64_t(0));
    CVarRef mthname = arr.rvalAtRef(int64_t(1));
    if (arr.size() != 2 ||
        &clsname == &null_variant ||
        &mthname == &null_variant) {
      name = v.toString();
      return false;
    }

    auto const tv_meth = mthname.asCell();
    if (!IS_STRING_TYPE(tv_meth->m_type)) {
      if (name.isReferenced()) name = v.toString();
      return false;
    }

    auto const tv_cls = clsname.asCell();
    if (tv_cls->m_type == KindOfObject) {
      name = tv_cls->m_data.pobj->o_getClassName();
    } else if (IS_STRING_TYPE(tv_cls->m_type)) {
      name = tv_cls->m_data.pstr;
    } else {
      name = v.toString();
      return false;
    }

    name = concat3(name, s_colon2, tv_meth->m_data.pstr);
    return ret;
  }

  if (tv_func->m_type == KindOfObject) {
    ObjectData *d = tv_func->m_data.pobj;
    const Func* invoke = d->getVMClass()->lookupMethod(s__invoke.get());
    if (name.isReferenced()) {
      if (d->instanceof(c_Closure::classof())) {
        // Hack to stop the mangled name from showing up
        name = s_Closure__invoke;
      } else {
        name = d->o_getClassName() + "::__invoke";
      }
    }
    return invoke != NULL;
  }

  return false;
}
Beispiel #15
0
static bool filter_func(CVarRef value, const void *data) {
  CallCtx* ctx = (CallCtx*)data;
  Variant ret;
  g_vmContext->invokeFuncFew((TypedValue*)&ret, *ctx, 1, value.asCell() );
  return ret.toBoolean();
}
Beispiel #16
0
CVarRef ArrayData::get(CVarRef k, bool error) const {
  assert(IsValidKey(k));
  auto const cell = k.asCell();
  return isIntKey(cell) ? get(getIntKey(cell), error)
                        : get(getStringKey(cell), error);
}
Object c_StaticResultWaitHandle::ti_create(CVarRef result) {
  return Create(*result.asCell());
}