コード例 #1
0
Variant MethodStatement::MethInvokerFewArgs(MethodCallPackage &mcp,
    int count, INVOKE_FEW_ARGS_IMPL_ARGS) {
  const MethodStatementWrapper *msw = (const MethodStatementWrapper*)mcp.extra;
  const MethodStatement *ms = msw->m_methodStatement;
  bool check = !ms->m_name->isame(s___invoke.get());
  bool isStatic = ms->getModifiers() & ClassStatement::Static;
  if (isStatic || !mcp.obj) {
    String cn;
    if (UNLIKELY(!isStatic && mcp.isObj && mcp.obj == NULL)) {
      // this is needed for continuations where
      // we are passed the dummy object
      cn = ms->getClass()->name();
    } else {
      cn = mcp.getClassName();
    }
    if (ms->refReturn()) {
      return strongBind(ms->invokeStaticFewArgs(cn, count,
        INVOKE_FEW_ARGS_PASS_ARGS, msw, check));
    } else {
      return ms->invokeStaticFewArgs(cn, count,
        INVOKE_FEW_ARGS_PASS_ARGS, msw, check);
    }
  } else {
    if (ms->refReturn()) {
      return strongBind(ms->invokeInstanceFewArgs(mcp.rootObj, count,
        INVOKE_FEW_ARGS_PASS_ARGS, msw, check));
    } else {
      return ms->invokeInstanceFewArgs(mcp.rootObj, count,
        INVOKE_FEW_ARGS_PASS_ARGS, msw, check);
    }
  }
}
コード例 #2
0
ファイル: ini-setting.cpp プロジェクト: 409033632/hhvm
void IniSetting::ParserCallback::makeArray(Variant &hash,
        const std::string &offset,
        const std::string &value) {
    assert(!offset.empty());
    Variant val = strongBind(hash);
    auto start = offset.c_str();
    auto p = start;
    bool last = false;
    do {
        String index(p);
        last = p + index.size() >= start + offset.size();
        Variant newval;
        if (last) {
            newval = Variant(value);
        } else {
            if (val.toArrRef().exists(index)) {
                newval = val.toArrRef().rvalAt(index);
            } else {
                newval = Variant(Array::Create());
            }
        }
        val.toArrRef().setRef(index, newval);
        if (!last) {
            val = strongBind(newval);
            p += index.size() + 1;
        }
    } while (!last);
}
コード例 #3
0
Variant IncOpExpression::refval(VariableEnvironment &env,
    int strict /* = 2 */) const {
  if (m_front) {
    return strongBind(eval(env));
  } else {
    return strongBind(Expression::refval(env, strict));
  }
}
コード例 #4
0
void c_MutableArrayIterator::t___construct(VRefParam array) {
  if (m_valid) {
    MArrayIter& mi = marr();
    mi.~MArrayIter();
    m_valid = false;
  }
  Variant var(strongBind(array));
  TypedValue* tv = (TypedValue*)(&var);
  assert(tv->m_type == KindOfRef);
  TypedValue* rtv = tv->m_data.pref->tv();
  if (rtv->m_type == KindOfArray) {
    MArrayIter& mi = marr();
    (void) new (&mi) MArrayIter(tv->m_data.pref);
    m_valid = mi.advance();
    if (!m_valid) mi.~MArrayIter();
  } else if (rtv->m_type == KindOfObject) {
    CStrRef ctxStr = g_vmContext->getContextClassName();
    if (rtv->m_data.pobj->isCollection()) {
      raise_error("Collection elements cannot be taken by reference");
    }
    bool isIterator;
    Object obj = rtv->m_data.pobj->iterableObject(isIterator);
    if (isIterator) {
      raise_error("An iterator cannot be used with foreach by reference");
    }
    Array iterArray = obj->o_toIterArray(ctxStr, true);
    ArrayData* ad = iterArray.detach();
    MArrayIter& mi = marr();
    (void) new (&mi) MArrayIter(ad);
    m_valid = mi.advance();
    if (!m_valid) mi.~MArrayIter();
  } else {
    raise_warning("Invalid argument supplied for foreach()");
  }
}
コード例 #5
0
ファイル: ext_array.cpp プロジェクト: 7755373049/hiphop-php
Variant f_hphp_current_ref(VRefParam array) {
  if (!array.isArray()) {
    throw_bad_array_exception();
    return false;
  }
  return strongBind(array.array_iter_current_ref());
}
コード例 #6
0
bool TestExtMemcached::test_Memcached_cas() {
  CREATE_MEMCACHED();
  for (ArrayIter iter(memc_version); iter; ++iter) {
    if (!f_version_compare(iter.second().toString(), "1.3.0", ">=")) {
      SKIP("Need memcached 1.3.0 for CAS");
      return Count(true);
    }
  }

  const char *key = "cas_test";

  VERIFY(memc->t_set(key, 10, EXPIRATION));

  Variant cas;

  VS(memc->t_get(key, null, strongBind(cas)), 10);

  VERIFY(!cas.isNull() && cas.isDouble());
  VERIFY(memc->t_cas(cas.toDouble(), key, 11, EXPIRATION));

  VS(memc->t_get(key, null, cas), 11);
  VERIFY(!memc->t_cas(cas.toDouble(), key, 12, EXPIRATION));
  VS(memc->t_get(key, null, cas), 11);

  return Count(true);
}
コード例 #7
0
ファイル: ext_iterator.cpp プロジェクト: BauerBox/hiphop-php
Variant c_MutableArrayIterator::t_currentref() {
    INSTANCE_METHOD_INJECTION_BUILTIN(MutableArrayIterator, MutableArrayIterator::currentref);
    if (!m_valid) return null;
    MArrayIter& mi = marr();
    if (mi.end()) return null;
    return strongBind(mi.val());
}
コード例 #8
0
ファイル: type_object.cpp プロジェクト: n3b/hiphop-php
Variant Object::o_argval(bool byRef, CStrRef propName,
                         bool error /* = true */, CStrRef context /* = null_string */) {
    if (!byRef) {
        return o_get(propName, error, context);
    } else {
        return strongBind(o_lval(propName, context));
    }
}
コード例 #9
0
ファイル: expression.cpp プロジェクト: HyeongKyu/hiphop-php
Variant Expression::refval(VariableEnvironment &env, int strict /* = 2 */)
  const {
  if (strict == 2) {
    raise_error("Value cannot be used in reference context");
  } else if (strict == 1) {
    raise_notice("Value cannot be used in reference context");
  }
  return strongBind(eval(env));
}
コード例 #10
0
Variant Array::argvalAt(bool byRef, CStrRef key,
                        bool isString /* = false */) const {
    if (byRef) {
        return strongBind(
                   const_cast<Array*>(this)->lvalAt(key, AccessFlags::IsKey(isString)));
    } else {
        return rvalAtRef(key);
    }
}
コード例 #11
0
Variant MethodStatement::evalBody(VariableEnvironment &env) const {
  if (isAbstract()) {
    raise_error("Cannot call abstract method %s()", m_fullName->data());
  }
  if (m_ref) {
    return strongBind(FunctionStatement::evalBody(env));
  } else {
    return FunctionStatement::evalBody(env);
  }
}
コード例 #12
0
ファイル: ini-setting.cpp プロジェクト: bseibel/hhvm
void IniSetting::ParserCallback::makeArray(Variant &hash,
                                           const std::string &offset,
                                           const std::string &value) {
  assert(!offset.empty());
  Variant val = strongBind(hash);
  auto start = offset.c_str();
  auto p = start;
  bool last = false;
  do {
    String index(p);
    last = p + index.size() >= start + offset.size();
    auto def = Variant(Array::Create());
    Variant newval = last ? Variant(value) : val.lvalRef(index, def);
    val.setRef(index, newval);
    if (!last) {
      val = strongBind(newval);
      p += index.size() + 1;
    }
  } while (!last);
}
コード例 #13
0
ファイル: array_data.cpp プロジェクト: hashaash/hiphop-php
ArrayData *ArrayData::CreateRef(CVarRef value) {
  if (enable_vector_array && RuntimeOption::UseVectorArray) {
    VectorArray *va = NEW(VectorArray)(1);
    va->m_elems[0] = NEW(Variant)(strongBind(value));
    va->m_size = 1;
    va->m_pos = 0;
    return va;
  }
  ArrayInit init(1);
  init.setRef(value);
  return init.create();
}
コード例 #14
0
Variant MethodStatement::invokeStatic(CStrRef cls, CArrRef params,
  const MethodStatementWrapper *msw, bool check /* = true */) const {
  ASSERT(msw->m_methodStatement == this);
  if (check) attemptAccess(FrameInjection::GetClassName(false), msw);
  DECLARE_THREAD_INFO_NOINIT
  MethScopeVariableEnvironment env(this);
  env.setCurrentClass(cls);
  env.setCurrentAlias(get_current_alias());
  EvalFrameInjection fi(msw->m_className, m_fullName->data(), env, loc()->file,
                        NULL, FrameInjection::StaticMethod);
  if (m_ref) {
    return strongBind(invokeImpl(env, params));
  }
  return invokeImpl(env, params);
}
コード例 #15
0
Variant ListAssignmentExpression::eval(VariableEnvironment &env) const {
  const VariableExpression *v = m_rhs->cast<VariableExpression>();
  if (v) {
    // Rhs has to be taken as lval if a variable in case there are references
    // to that variable on the lhs.
    CVarRef rhs(v->lval(env));
    Variant tmp(strongBind(rhs));
    m_lhs->set(env, tmp);
    return rhs;
  } else {
    Variant rhs(m_rhs->eval(env));
    m_lhs->set(env, !m_abnormal || rhs.is(KindOfArray) ? rhs : null_variant);
    return rhs;
  }
}
コード例 #16
0
Variant MethodStatement::invokeStaticFewArgs(CStrRef cls, int count,
  INVOKE_FEW_ARGS_IMPL_ARGS, const MethodStatementWrapper *msw, bool check)
  const {
  ASSERT(msw->m_methodStatement == this);
  if (check) attemptAccess(FrameInjection::GetClassName(false), msw);
  DECLARE_THREAD_INFO_NOINIT
  MethScopeVariableEnvironment env(this);
  env.setCurrentClass(cls);
  env.setCurrentAlias(get_current_alias());
  EvalFrameInjection fi(msw->m_className, m_fullName->data(), env, loc()->file,
                        NULL, FrameInjection::StaticMethod);
  if (m_ref) {
    return strongBind(invokeImplFewArgs(env, count, INVOKE_FEW_ARGS_PASS_ARGS));
  }
  return invokeImplFewArgs(env, count, INVOKE_FEW_ARGS_PASS_ARGS);
}
コード例 #17
0
void c_MutableArrayIterator::t___construct(VRefParam array) {
  INSTANCE_METHOD_INJECTION_BUILTIN(MutableArrayIterator, MutableArrayIterator::__construct);
  if (m_valid) {
    MIterCtx& mi = marr();
    mi.~MIterCtx();
    m_valid = false;
  }
  Variant var(strongBind(array));
  TypedValue* tv = (TypedValue*)(&var);
  ASSERT(tv->m_type == KindOfRef);
  if (tv->m_data.ptv->m_type == KindOfArray) {
    ArrayData* ad = tv->m_data.ptv->m_data.parr;
    if (ad->getCount() > 1) {
      ArrayData* copy = ad->copy();
      copy->incRefCount();
      ad->decRefCount();  // count > 1 to begin with; don't need release
      ad = tv->m_data.ptv->m_data.parr = copy;
    }
    MIterCtx& mi = marr();
    (void) new (&mi) MIterCtx(tv->m_data.pref);
    m_valid = mi.m_mArray->advance();
    if (!m_valid) mi.~MIterCtx();
  } else if (tv->m_data.ptv->m_type == KindOfObject) {
    CStrRef ctxStr = hhvm
                     ? g_vmContext->getContextClassName(true)
                     : FrameInjection::GetClassName(true);
    bool isIterator;
    Object obj = tv->m_data.ptv->m_data.pobj->iterableObject(isIterator);
    if (isIterator) {
      raise_error("An iterator cannot be used with foreach by reference");
    }
    Array iterArray = obj->o_toIterArray(ctxStr, true);
    ArrayData* ad = iterArray.getArrayData();
    if (ad->getCount() > 1) {
      ArrayData* copy = ad->copy();
      copy->incRefCount();
      ad->decRefCount();  // count > 1 to begin with; don't need release
      ad = copy;
    }
    MIterCtx& mi = marr();
    (void) new (&mi) MIterCtx(ad);
    m_valid = mi.m_mArray->advance();
    if (!m_valid) mi.~MIterCtx();
  } else {
    raise_warning("Invalid argument supplied for foreach()");
  }
}
コード例 #18
0
Variant MethodStatement::invokeInstance(CObjRef obj, CArrRef params,
  const MethodStatementWrapper *msw, bool check /* = true */) const {
  ASSERT(msw->m_methodStatement == this);
  if (getModifiers() & ClassStatement::Static) {
    return invokeStatic(obj->o_getClassName(), params, msw, check);
  }
  if (check) attemptAccess(FrameInjection::GetClassName(false), msw);
  // The debug frame should have been pushed at ObjectMethodExpression
  DECLARE_THREAD_INFO_NOINIT
  MethScopeVariableEnvironment env(this);
  env.setCurrentObject(obj);
  env.setCurrentAlias(get_current_alias());
  EvalFrameInjection fi(msw->m_className, m_fullName->data(), env,
                        loc()->file, obj.get(), FrameInjection::ObjectMethod);
  if (m_ref) {
    return strongBind(invokeImpl(env, params));
  }
  return invokeImpl(env, params);
}
コード例 #19
0
ファイル: zend_array.cpp プロジェクト: HyeongKyu/hiphop-php
bool ZendArray::nextInsertRef(CVarRef data) {
  if (m_nNextFreeElement < 0) {
    raise_warning("Cannot add element to the array as the next element is "
                  "already occupied");
    return false;
  }
  int64 h = m_nNextFreeElement;
  Bucket * p = NEW(Bucket)(strongBind(data));
  p->h = h;
  uint nIndex = (h & m_nTableMask);
  CONNECT_TO_BUCKET_LIST(p, m_arBuckets[nIndex]);
  SET_ARRAY_BUCKET_HEAD(m_arBuckets, nIndex, p);
  CONNECT_TO_GLOBAL_DLLIST(p);
  m_nNextFreeElement = h + 1;
  if (++m_nNumOfElements > m_nTableSize) {
    resize();
  }
  return true;
}
コード例 #20
0
Variant MethodStatement::
invokeStaticDirect(CStrRef cls, CStrRef alias, VariableEnvironment &env,
                   const FunctionCallExpression *caller, bool sp,
                   const MethodStatementWrapper *msw,
                   bool check /* = true */)
  const {
  ASSERT(msw->m_methodStatement == this);
  if (check) attemptAccess(FrameInjection::GetClassName(false), msw);
  MethScopeVariableEnvironment fenv(this);
  directBind(env, caller, fenv);
  fenv.setCurrentClass(cls);
  fenv.setCurrentAlias(alias);
  EvalFrameInjection::EvalStaticClassNameHelper helper(cls, sp);
  DECLARE_THREAD_INFO_NOINIT
  EvalFrameInjection fi(msw->m_className, m_fullName->data(), fenv,
                        loc()->file, NULL, FrameInjection::StaticMethod);
  if (m_ref) {
    return strongBind(evalBody(fenv));
  }
  return evalBody(fenv);
}
コード例 #21
0
ファイル: zend_array.cpp プロジェクト: DenisBazhan/hiphop-php
bool ZendArray::updateRef(StringData *key, CVarRef data) {
  int64 h = key->hash();
  Bucket *p = findForInsert(key->data(), key->size(), h);
  if (p) {
    p->data.assignRefHelper(data);
    return true;
  }

  p = NEW(Bucket)(strongBind(data));
  p->setStrKey(key, h);

  uint nIndex = (h & m_nTableMask);
  CONNECT_TO_BUCKET_LIST(p, m_arBuckets[nIndex]);
  SET_ARRAY_BUCKET_HEAD(m_arBuckets, nIndex, p);
  CONNECT_TO_GLOBAL_DLLIST(p);

  if (++m_size > tableSize()) {
    resize();
  }
  return true;
}
コード例 #22
0
ファイル: zend_array.cpp プロジェクト: HyeongKyu/hiphop-php
bool ZendArray::updateRef(int64 h, CVarRef data) {
  Bucket *p = find(h);
  if (p) {
    p->data.assignRefHelper(data);
    return true;
  }

  p = NEW(Bucket)(strongBind(data));
  p->h = h;

  uint nIndex = (h & m_nTableMask);
  CONNECT_TO_BUCKET_LIST(p, m_arBuckets[nIndex]);
  SET_ARRAY_BUCKET_HEAD(m_arBuckets, nIndex, p);
  CONNECT_TO_GLOBAL_DLLIST(p);

  if (h >= m_nNextFreeElement && m_nNextFreeElement >= 0) {
    m_nNextFreeElement = h + 1;
  }
  if (++m_nNumOfElements > m_nTableSize) {
    resize();
  }
  return true;
}
コード例 #23
0
ファイル: zend_array.cpp プロジェクト: HyeongKyu/hiphop-php
bool ZendArray::updateRef(StringData *key, CVarRef data) {
  int64 h = key->hash();
  Bucket *p = find(key->data(), key->size(), h);
  if (p) {
    p->data.assignRefHelper(data);
    return true;
  }

  p = NEW(Bucket)(strongBind(data));
  p->key = key;
  p->key->incRefCount();
  p->h = h;

  uint nIndex = (h & m_nTableMask);
  CONNECT_TO_BUCKET_LIST(p, m_arBuckets[nIndex]);
  SET_ARRAY_BUCKET_HEAD(m_arBuckets, nIndex, p);
  CONNECT_TO_GLOBAL_DLLIST(p);

  if (++m_nNumOfElements > m_nTableSize) {
    resize();
  }
  return true;
}
コード例 #24
0
Variant MethodStatement::
invokeInstanceDirect(CObjRef obj, CStrRef alias, VariableEnvironment &env,
                     const FunctionCallExpression *caller,
                     const MethodStatementWrapper *msw,
                     bool check /* = true */) const {
  ASSERT(msw->m_methodStatement == this);
  if (getModifiers() & ClassStatement::Static) {
    return invokeStaticDirect(obj->o_getClassName(), alias, env,
                              caller, false, msw, check);
  }
  if (check) attemptAccess(FrameInjection::GetClassName(false), msw);
  DECLARE_THREAD_INFO_NOINIT
  MethScopeVariableEnvironment fenv(this);
  directBind(env, caller, fenv);
  fenv.setCurrentObject(obj);
  fenv.setCurrentAlias(alias);
  EvalFrameInjection::EvalStaticClassNameHelper helper(obj);
  EvalFrameInjection fi(msw->m_className, m_fullName->data(), fenv,
                        loc()->file, obj.get(), FrameInjection::ObjectMethod);
  if (m_ref) {
    return strongBind(evalBody(fenv));
  }
  return evalBody(fenv);
}
コード例 #25
0
Variant LvalExpression::refval(VariableEnvironment &env,
    int strict /* = 2 */) const {
  return strongBind(lval(env));
}
コード例 #26
0
bool TestCppBase::TestVariant() {
  // operators
  {
    Variant v(15);
    v += 20;
    VERIFY(v.isNumeric());
    VERIFY(v.is(KindOfInt64));
    VERIFY(v == Variant(35));
  }

  // conversions
  {
    Variant v("123");
    VERIFY(v.toInt32() == 123);
  }

  // offset
  {
    Variant v = "test";
    VS(v.rvalAt(0), "t");
  }
  {
    Variant v;
    v.lvalAt(0) = String("v0");
    v.lvalAt(1) = String("v1");
    VERIFY(v[0] == "v0");
    VERIFY(v[1] == "v1");
  }
  {
    Variant v;
    v.lvalAt() = String("test");
    VS(v, CREATE_VECTOR1("test"));
  }
  {
    Variant v;
    v.lvalAt(1) = String("test");
    VS(v[1], "test");
    VS(v[1.5], "test");
    VS(v[Variant(1.5)], "test");
    VS(v[s_1], "test");
    VS(v[Variant("1")], "test");
  }
  {
    Variant v;
    v.lvalAt(Variant(1.5)) = String("test");
    VS(v[1], "test");
    VS(v[1.5], "test");
    VS(v[Variant(1.5)], "test");
    VS(v[s_1], "test");
    VS(v[Variant("1")], "test");
  }
  {
    Variant v;
    v.lvalAt(s_1) = String("test");
    VS(v[1], "test");
    VS(v[1.5], "test");
    VS(v[Variant(1.5)], "test");
    VS(v[s_1], "test");
    VS(v[Variant("1")], "test");
  }
  {
    Variant v;
    v.lvalAt(Variant("1")) = String("test");
    VS(v[1], "test");
    VS(v[1.5], "test");
    VS(v[Variant(1.5)], "test");
    VS(v[s_1], "test");
    VS(v[Variant("1")], "test");
  }

  // membership
  {
    Variant v;
    v.lvalAt(s_n0) = String("v0");
    v.lvalAt(s_n1) = String("v1");
    v.remove(s_n1);
    VS(v, CREATE_MAP1(s_n0, "v0"));
    v.append("v2");
    VS(v, CREATE_MAP2(s_n0, "v0", 0, "v2"));
  }
  {
    Variant v;
    v.lvalAt(s_n0) = String("v0");
    v.lvalAt(1) = String("v1");
    v.remove(Variant(1.5));
    VS(v, CREATE_MAP1("n0", "v0"));
  }
  {
    Variant v;
    v.lvalAt(s_n0) = String("v0");
    v.lvalAt(1) = String("v1");
    v.remove(Variant("1"));
    VS(v, CREATE_MAP1("n0", "v0"));
  }
  {
    Variant v;
    v.lvalAt(s_n0) = String("v0");
    v.lvalAt(1) = String("v1");
    v.remove(String("1"));
    VS(v, CREATE_MAP1("n0", "v0"));
  }
  {
    Variant v;
    v.lvalAt(s_n0) = String("v0");
    v.lvalAt(empty_string) = String("v1");
    v.remove(Variant());
    VS(v, CREATE_MAP1("n0", "v0"));
  }

  // references
  {
    Variant v1("original");
    Variant v2 = v1;
    v2 = String("changed");
    VERIFY(v1 == "original");
  }
  {
    Variant v1("original");
    Variant v2 = strongBind(v1);
    v2 = String("changed");
    VERIFY(v1 == "changed");
  }
  {
    Variant v1 = 10;
    Variant v2 = Array(ArrayInit(1).setRef(v1).create());
    v1 = 20;
    VS(v2[0], 20);
  }
  {
    Variant v1 = 10;
    Variant v2;
    v2.lvalAt() = ref(v1);
    v1 = 20;
    VS(v2[0], 20);
  }
  {
    Variant v1 = 10;
    Variant v2 = CREATE_VECTOR1(5);
    v2.lvalAt() = ref(v1);
    v1 = 20;
    VS(v2[1], 20);
  }
  {
    Variant v1 = 10;
    Variant v2 = strongBind(v1);
    v2++;
    VS(v2, 11);
    VS(v1, 11);
  }
  {
    Variant arr = CREATE_VECTOR2(1, 2);
    Variant v;
    for (MutableArrayIter iter = arr.begin(nullptr, v); iter.advance();) {
      v++;
    }
    VS(arr, CREATE_VECTOR2(2, 3));
  }

  // array escalation
  {
    Variant arr;
    lval(arr.lvalAt(0)).lvalAt(0) = 1.2;
    VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
  }
  {
    Variant arr;
    lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
    VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2)));
  }
  {
    Variant arr = Array::Create();
    lval(arr.lvalAt(0)).lvalAt(0) = 1.2;
    VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
  }
  {
    Variant arr = Array::Create();
    lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
    VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2)));
  }
  {
    Variant arr = Array::Create("test");
    arr.lvalAt(0) = CREATE_VECTOR1(1.2);
    VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
  }
  {
    Variant arr = Array::Create("test");
    lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
    VS(arr, CREATE_MAP2(0, "test", s_name, CREATE_VECTOR1(1.2)));
  }

  return Count(true);
}
コード例 #27
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())));
}
コード例 #28
0
Variant c_MutableArrayIterator::t_currentref() {
  if (!m_valid) return uninit_null();
  MArrayIter& mi = marr();
  if (mi.end()) return uninit_null();
  return strongBind(mi.val());
}
コード例 #29
0
Variant Array::refvalAt(CStrRef key, bool isString /* = false */) {
    return strongBind(lvalAt(key, AccessFlags::IsKey(isString)));
}
コード例 #30
0
Variant c_MutableArrayIterator::t_currentref() {
  INSTANCE_METHOD_INJECTION_BUILTIN(MutableArrayIterator, MutableArrayIterator::currentref);
  if (!m_valid) return null;
  MIterCtx& mi = marr();
  return strongBind(*(Variant*)(&mi.m_val));
}