Arquivos
hhvm/hphp/runtime/base/hphp_system.cpp
T
Jordan Delong 363d1bb20f Code move src/ -> hphp/
This change is mostly for FB internal organizational reasons.
Building is not effected beyond the fact that the target now
lands in hphp/hhvm/hhvm rather than src/hhvm/hhvm.
2013-02-11 02:10:41 -08:00

231 linhas
6.2 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- 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 <runtime/base/hphp_system.h>
#include <runtime/base/compiler_id.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
Globals::StaticInits *Globals::s_next_inits = 0;
void Globals::initialize() {
StaticInits *s = s_next_inits;
while (s) {
const ClassPropTable *cpt = s->table;
const int *e = s->entries;
int n = *e++;
while (n--) {
const ClassPropTableEntry *p = cpt->m_entries + *e++;
char *addr = (char*)this + p->offset;
if (LIKELY(p->isFastInit())) {
CVarRef v = cpt->getInitV(p->init_offset);
switch (p->type) {
case KindOfBoolean:
*(bool*)addr = v.asBooleanVal();
break;
case KindOfInt64:
*(int64*)addr = v.asInt64Val();
break;
case KindOfDouble:
*(double*)addr = v.asDoubleVal();
break;
case KindOfString:
*(String*)addr = v.asCStrRef();
break;
case KindOfArray:
*(Array*)addr = v.asCArrRef();
break;
case KindOfUnknown:
*(Variant*)addr = v;
break;
default:
assert(false);
}
continue;
}
CVarRef v = cpt->getInitVal(p);
if (LIKELY(p->type == KindOfUnknown)) {
*(Variant*)addr = v;
} else {
switch (p->type) {
case KindOfBoolean:
*(bool*)addr = v;
break;
case KindOfInt64:
*(int64*)addr = v;
break;
case KindOfDouble:
*(double*)addr = v;
break;
case KindOfString:
*(String*)addr = v;
break;
case KindOfArray:
*(Array*)addr = v;
break;
default:
assert(false);
}
}
}
s = s->next;
}
}
bool Globals::declareConstant(CStrRef name, Variant &constant,
CVarRef value) {
if (!value.isAllowedAsConstantValue()) {
raise_warning("Constants may only evaluate to scalar values");
return false;
}
if (!m_dynamicConstants.exists(name)) {
m_dynamicConstants.set(name, value);
constant = value;
return true;
}
raise_warning("Constant %s already defined", name.data());
return false;
}
bool Globals::defined(CStrRef name) {
return m_dynamicConstants.exists(name);
}
Variant Globals::getConstant(CStrRef name) {
return m_dynamicConstants[name];
}
Array Globals::getDynamicConstants() const {
return m_dynamicConstants;
}
Variant Globals::getByIdx(ssize_t pos, Variant& k) {
return getRefByIdx(pos, k);
}
CVarRef Globals::getRefByIdx(ssize_t pos, Variant& k) {
if (pos < -1) {
ArrayData *arr = Array::get();
pos = wrapIter(pos);
k = arr->getKey(pos);
return arr->getValueRef(pos);
}
assert(false);
throw FatalErrorException("bad code generation");
}
ssize_t Globals::getIndex(const char* s, strhash_t prehash) const {
return Array::get()->getIndex(s);
}
ssize_t Globals::size() const {
return staticSize() + Array::size();
}
bool Globals::empty() const {
return staticSize() == 0 && Array::size() == 0;
}
ssize_t Globals::staticSize() const { return 0; }
ssize_t Globals::iter_begin() const {
if (empty()) return ArrayData::invalid_index;
if (staticSize() > 0) {
return 0;
}
return wrapIter(Array::get()->iter_begin());
}
ssize_t Globals::iter_end() const {
if (empty()) return ArrayData::invalid_index;
if (Array::size() > 0) {
return wrapIter(Array::get()->iter_end());
}
return staticSize() - 1;
}
ssize_t Globals::iter_advance(ssize_t prev) const {
ArrayData *arr = Array::get();
if (prev < -1) {
return wrapIter(arr->iter_advance(wrapIter(prev)));
}
ssize_t next = prev + 1;
if (next == staticSize()) {
if (arr) return wrapIter(arr->iter_begin());
return ArrayData::invalid_index;
}
return next;
}
ssize_t Globals::iter_rewind(ssize_t prev) const {
if (prev < -1) {
ArrayData *arr = Array::get();
assert(arr);
ssize_t next = arr->iter_rewind(wrapIter(prev));
if (next == ArrayData::invalid_index) {
if (staticSize() > 0) {
return staticSize() - 1;
}
return ArrayData::invalid_index;
} else {
return wrapIter(next);
}
}
ssize_t next = prev - 1;
if (next < 0) return ArrayData::invalid_index;
return next;
}
void Globals::getFullPos(FullPos &pos) {
ArrayData *arr = Array::get();
arr->getFullPos(pos);
}
bool Globals::setFullPos(const FullPos &pos) {
ArrayData *arr = Array::get();
return arr->setFullPos(pos);
}
Array Globals::getDefinedVars() {
Array ret = Array::Create();
for (ssize_t iter = iter_begin(); iter != ArrayData::invalid_index;
iter = iter_advance(iter)) {
Variant k;
Variant v = getByIdx(iter, k);
ret.set(k, v);
}
return ret;
}
ssize_t Globals::wrapIter(ssize_t it) const {
if (it != ArrayData::invalid_index) {
return -(it+2);
}
return ArrayData::invalid_index;
}
#ifdef HPHP_VERSION
#undef HPHP_VERSION
#endif
#define HPHP_VERSION(v) return #v;
const char* getHphpCompilerVersion() {
#include "../../version"
}
const char* getHphpCompilerId() {
#ifdef COMPILER_ID
return COMPILER_ID;
#else
return "";
#endif
}
///////////////////////////////////////////////////////////////////////////////
}