9edc07112b
When object support was first added to HHVM, a class named "Instance" was introduced (deriving from ObjectData) to represent instances of user defined classes. Since then, things have evolved and HPHPc and HPHPi have been retired, and now there really is no needed to have ObjectData and Instance be separate classes anymore. As a first step towards merging ObjectData and Instance together, this diff puts their definitions in the same .h file and puts their implementations in the same .cpp file. A few small changes were necessary to fix issues with cyclical includes: (1) Repo/emitter related parts of class.cpp and class.h were moved to class-emit.cpp and class-emit.h; (2) the contents of "vm/core_types.h" was moved to "base/types.h"; and (3) a few functions that didn't appear to be hot were moved from .h files and the corresponding .cpp files.
241 linhas
7.4 KiB
C++
241 linhas
7.4 KiB
C++
/*
|
|
+----------------------------------------------------------------------+
|
|
| HipHop for PHP |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 3.01 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available through the world-wide-web at the following url: |
|
|
| http://www.php.net/license/3_01.txt |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
#include "hphp/runtime/vm/name_value_table_wrapper.h"
|
|
#include "hphp/runtime/base/runtime_error.h"
|
|
#include "hphp/runtime/base/array/array_iterator.h"
|
|
#include "hphp/runtime/base/array/array_init.h"
|
|
|
|
namespace HPHP {
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
ssize_t NameValueTableWrapper::vsize() const {
|
|
// We need to iterate to find out the actual size, since
|
|
// KindOfIndirect elements in the array may have been set to
|
|
// KindOfUninit.
|
|
ssize_t count = 0;
|
|
for (ssize_t iter = iter_begin();
|
|
iter != ArrayData::invalid_index;
|
|
iter = iter_advance(iter)) {
|
|
++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
void NameValueTableWrapper::nvGetKey(TypedValue* out, ssize_t pos) const {
|
|
NameValueTable::Iterator iter(m_tab, pos);
|
|
if (iter.valid()) {
|
|
auto k = iter.curKey();
|
|
out->m_data.pstr = const_cast<StringData*>(k);
|
|
out->m_type = KindOfString;
|
|
k->incRefCount();
|
|
} else {
|
|
out->m_type = KindOfUninit;
|
|
}
|
|
}
|
|
|
|
CVarRef NameValueTableWrapper::getValueRef(ssize_t pos) const {
|
|
NameValueTable::Iterator iter(m_tab, pos);
|
|
return iter.valid() ? tvAsCVarRef(iter.curVal()) : null_variant;
|
|
}
|
|
|
|
bool NameValueTableWrapper::noCopyOnWrite() const {
|
|
// This just disables a few places that will call copy() on an array
|
|
// if it has more than one reference.
|
|
return true;
|
|
}
|
|
|
|
bool NameValueTableWrapper::exists(int64_t k) const {
|
|
return exists(String(k));
|
|
}
|
|
|
|
bool NameValueTableWrapper::exists(const StringData* k) const {
|
|
return m_tab->lookup(k);
|
|
}
|
|
|
|
bool NameValueTableWrapper::idxExists(ssize_t idx) const {
|
|
return false;
|
|
}
|
|
|
|
TypedValue* NameValueTableWrapper::nvGet(const StringData* k) const {
|
|
return m_tab->lookup(k);
|
|
}
|
|
|
|
TypedValue* NameValueTableWrapper::nvGet(int64_t k) const {
|
|
return m_tab->lookup(String(k).get());
|
|
}
|
|
|
|
TypedValue* NameValueTableWrapper::nvGetCell(int64_t k) const {
|
|
TypedValue* tv = NameValueTableWrapper::nvGet(k);
|
|
return tv ? tvToCell(tv) : nvGetNotFound(k);
|
|
}
|
|
|
|
TypedValue* NameValueTableWrapper::nvGetCell(const StringData* key) const {
|
|
TypedValue* tv = NameValueTableWrapper::nvGet(key);
|
|
return tv ? tvToCell(tv) : nvGetNotFound(key);
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::lval(int64_t k, Variant*& ret, bool copy,
|
|
bool checkExist) {
|
|
return lval(String(k), ret, copy, checkExist);
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::lval(StringData* k, Variant*& ret,
|
|
bool copy, bool checkExist) {
|
|
TypedValue* tv = m_tab->lookup(k);
|
|
if (!tv) {
|
|
TypedValue nulVal;
|
|
tvWriteNull(&nulVal);
|
|
tv = m_tab->set(k, &nulVal);
|
|
}
|
|
ret = &tvAsVariant(tv);
|
|
return this;
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::lvalNew(Variant*& ret, bool copy) {
|
|
ret = &Variant::lvalBlackHole();
|
|
return this;
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::set(int64_t k, CVarRef v, bool copy) {
|
|
return set(String(k), v, copy);
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::set(StringData* k, CVarRef v,
|
|
bool copy) {
|
|
tvAsVariant(m_tab->lookupAdd(k)).assignVal(v);
|
|
return this;
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::setRef(int64_t k, CVarRef v, bool copy) {
|
|
return setRef(String(k), v, copy);
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::setRef(StringData* k, CVarRef v, bool copy) {
|
|
tvAsVariant(m_tab->lookupAdd(k)).assignRef(v);
|
|
return this;
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::remove(int64_t k, bool copy) {
|
|
return remove(String(k), copy);
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::remove(const StringData* k, bool copy) {
|
|
m_tab->unset(k);
|
|
return this;
|
|
}
|
|
|
|
/*
|
|
* The messages in the user-visible exceptions below claim we are
|
|
* $GLOBALS, because the only user-visible NameValueTableWrapper array
|
|
* is currently $GLOBALS.
|
|
*/
|
|
|
|
ArrayData* NameValueTableWrapper::append(CVarRef v, bool copy) {
|
|
throw NotImplementedException("append on $GLOBALS");
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::appendRef(CVarRef v, bool copy) {
|
|
throw NotImplementedException("appendRef on $GLOBALS");
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::appendWithRef(CVarRef v, bool copy) {
|
|
throw NotImplementedException("appendWithRef on $GLOBALS");
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::plus(const ArrayData* elems, bool copy) {
|
|
throw NotImplementedException("plus on $GLOBALS");
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::merge(const ArrayData* elems, bool copy) {
|
|
throw NotImplementedException("merge on $GLOBALS");
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::prepend(CVarRef v, bool copy) {
|
|
throw NotImplementedException("prepend on $GLOBALS");
|
|
}
|
|
|
|
ssize_t NameValueTableWrapper::iter_begin() const {
|
|
NameValueTable::Iterator iter(m_tab);
|
|
return iter.toInteger();
|
|
}
|
|
|
|
ssize_t NameValueTableWrapper::iter_end() const {
|
|
return NameValueTable::Iterator::getEnd(m_tab).toInteger();
|
|
}
|
|
|
|
ssize_t NameValueTableWrapper::iter_advance(ssize_t prev) const {
|
|
NameValueTable::Iterator iter(m_tab, prev);
|
|
iter.next();
|
|
return iter.toInteger();
|
|
}
|
|
|
|
ssize_t NameValueTableWrapper::iter_rewind(ssize_t prev) const {
|
|
NameValueTable::Iterator iter(m_tab, prev);
|
|
iter.prev();
|
|
return iter.toInteger();
|
|
}
|
|
|
|
bool NameValueTableWrapper::validFullPos(const FullPos & fp) const {
|
|
assert(fp.getContainer() == (ArrayData*)this);
|
|
if (fp.getResetFlag()) return false;
|
|
if (fp.m_pos == ArrayData::invalid_index) return false;
|
|
NameValueTable::Iterator iter(m_tab, fp.m_pos);
|
|
return (iter.valid());
|
|
}
|
|
|
|
bool NameValueTableWrapper::advanceFullPos(FullPos& fp) {
|
|
bool reset = fp.getResetFlag();
|
|
NameValueTable::Iterator iter = reset ?
|
|
NameValueTable::Iterator(m_tab) :
|
|
NameValueTable::Iterator(m_tab, fp.m_pos);
|
|
if (reset) {
|
|
fp.setResetFlag(false);
|
|
} else {
|
|
if (!iter.valid()) {
|
|
return false;
|
|
}
|
|
iter.next();
|
|
}
|
|
fp.m_pos = iter.toInteger();
|
|
if (!iter.valid()) return false;
|
|
// To conform to PHP behavior, we need to set the internal
|
|
// cursor to point to the next element.
|
|
iter.next();
|
|
m_pos = iter.toInteger();
|
|
return true;
|
|
}
|
|
|
|
ArrayData* NameValueTableWrapper::escalateForSort() {
|
|
raise_warning("Sorting the $GLOBALS array is not supported");
|
|
return this;
|
|
}
|
|
void NameValueTableWrapper::ksort(int sort_flags, bool ascending) {}
|
|
void NameValueTableWrapper::sort(int sort_flags, bool ascending) {}
|
|
void NameValueTableWrapper::asort(int sort_flags, bool ascending) {}
|
|
void NameValueTableWrapper::uksort(CVarRef cmp_function) {}
|
|
void NameValueTableWrapper::usort(CVarRef cmp_function) {}
|
|
void NameValueTableWrapper::uasort(CVarRef cmp_function) {}
|
|
|
|
bool NameValueTableWrapper::isVectorData() const {
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
}
|