Example #1
0
APCHandle* APCArray::MakeShared(ArrayData* arr,
                                bool inner,
                                bool unserializeObj) {
  if (!inner) {
    // only need to call traverseData() on the toplevel array
    DataWalker walker(DataWalker::LookupFeature::HasObjectOrResource);
    DataWalker::DataFeature features = walker.traverseData(arr);
    if (features.isCircular() || features.hasCollection()) {
      String s = apc_serialize(arr);
      APCHandle* handle = APCString::MakeShared(KindOfArray, s.get());
      handle->setSerializedArray();
      handle->mustCache();
      return handle;
    } else if (apcExtension::UseUncounted &&
               !features.hasObjectOrResource()) {
      return APCTypedValue::MakeSharedArray(arr);
    }
  }

  if (arr->isVectorData()) {
    return APCArray::MakePackedShared(arr, unserializeObj);
  }

  return APCArray::MakeShared(arr, unserializeObj);
}
Example #2
0
Array f_get_class_constants(const String& className) {
    auto const cls = Unit::loadClass(className.get());
    if (cls == NULL) {
        return Array::attach(HphpArray::MakeReserve(0));
    }

    auto const numConstants = cls->numConstants();
    ArrayInit arrayInit(numConstants);

    auto const consts = cls->constants();
    for (size_t i = 0; i < numConstants; i++) {
        // Note: hphpc doesn't include inherited constants in
        // get_class_constants(), so mimic that behavior
        if (consts[i].m_class == cls) {
            auto const name  = const_cast<StringData*>(consts[i].m_name);
            Cell value = consts[i].m_val;
            // Handle dynamically set constants
            if (value.m_type == KindOfUninit) {
                value = cls->clsCnsGet(consts[i].m_name);
            }
            assert(value.m_type != KindOfUninit);
            arrayInit.set(name, cellAsCVarRef(value), true /* isKey */);
        }
    }

    return arrayInit.toArray();
}
Example #3
0
SmartPtr<File>
FileStreamWrapper::open(const String& filename, const String& mode,
                        int options, const SmartPtr<StreamContext>& context) {
  String fname;
  if (StringUtil::IsFileUrl(filename)) {
    fname = StringUtil::DecodeFileUrl(filename);
    if (fname.empty()) {
      raise_warning("invalid file:// URL");
      return nullptr;
    }
  } else {
    fname = filename;
  }

  if (auto file = openFromCache(fname, mode)) {
    return file;
  }

  if (options & File::USE_INCLUDE_PATH) {
    struct stat s;
    String resolved_fname = resolveVmInclude(fname.get(), "", &s);
    if (!resolved_fname.isNull()) {
      fname = resolved_fname;
    }
  }

  auto file = makeSmartPtr<PlainFile>();
  bool ret = file->open(File::TranslatePath(fname), mode);
  if (!ret) {
    raise_warning("%s", file->getLastError().c_str());
    return nullptr;
  }
  return file;
}
Example #4
0
bool TestDebugger::getResponse(const string& path, string& result,
                               int port /* = -1 */,
                               const string& host /* = "" */) {
  String server = "http://";
  if (host.empty()) {
    server += f_php_uname("n");
  } else {
    server += host;
  }
  server += ":" + boost::lexical_cast<string>(port > 0 ? port : m_serverPort);
  server += "/" + path;
  printf("\n  Getting URL '%s'...\n", server.get()->data());
  Variant c = f_curl_init();
  f_curl_setopt(c.toResource(), k_CURLOPT_URL, server);
  f_curl_setopt(c.toResource(), k_CURLOPT_RETURNTRANSFER, true);
  f_curl_setopt(c.toResource(), CURLOPT_TIMEOUT, 120);
  Variant res = f_curl_exec(c.toResource());
  if (same(res, false)) {
    printf("  Request failed\n");
    return false;
  }
  result = (std::string) res.toString();
  printf("  Request succeeded, returning '%s'\n", result.c_str());
  return true;
}
Example #5
0
const Class* ClassCache::lookup(RDS::Handle handle, StringData* name) {
  auto const thiz = handleToPtr<ClassCache>(handle);
  auto const pair = keyToPair(thiz, name);
  const StringData* pairSd = pair->m_key;
  if (!stringMatches(pairSd, name)) {
    TRACE(1, "ClassCache miss: %s\n", name->data());
    const NamedEntity *ne = Unit::GetNamedEntity(name);
    Class *c = Unit::lookupClass(ne);
    if (UNLIKELY(!c)) {
      String normName = normalizeNS(name);
      if (normName) {
        return lookup(handle, normName.get());
      } else {
        c = Unit::loadMissingClass(ne, name);
      }
      if (UNLIKELY(!c)) {
        raise_error(Strings::UNKNOWN_CLASS, name->data());
      }
    }

    if (pair->m_key) decRefStr(pair->m_key);
    pair->m_key = name;
    name->incRefCount();
    pair->m_value = c;
  } else {
    TRACE(1, "ClassCache hit: %s\n", name->data());
  }
  return pair->m_value;
}
Example #6
0
Variant f_eval(CStrRef code_str) {
  String prefixedCode = concat("<?php ", code_str);
  Unit* unit = g_vmContext->compileEvalString(prefixedCode.get());
  TypedValue retVal;
  g_vmContext->invokeUnit(&retVal, unit);
  return tvAsVariant(&retVal);
}
Example #7
0
bool f_define(const String& name, const Variant& value,
              bool case_insensitive /* = false */) {
  if (case_insensitive) {
    raise_warning(Strings::CONSTANTS_CASE_SENSITIVE);
  }
  return Unit::defCns(name.get(), value.asCell());
}
Example #8
0
void XDebugHookHandler::onExceptionThrown(ObjectData* exception) {
  // Grab the exception name and message
  const StringData* name = exception->getVMClass()->name();
  const Variant msg = exception->o_invoke(s_GET_MESSAGE, init_null(), false);
  const String msg_str = msg.isNull() ? empty_string() : msg.toString();
  onExceptionBreak(name, msg.isNull() ? nullptr : msg_str.get());
}
Example #9
0
bool f_function_exists(const String& function_name,
                       bool autoload /* = true */) {
  return
    function_exists(function_name) ||
    (autoload &&
     AutoloadHandler::s_instance->autoloadFunc(function_name.get()) &&
     function_exists(function_name));
}
Example #10
0
const StringData*
encodeCallAndArgs(const StringData* name, int numArgs) {
  char numArgsBuf[16];
  if (numArgs > s_maxNumArgs) s_maxNumArgs = numArgs;
  snprintf(numArgsBuf, 15, "@%d@", numArgs);
  String s = String(numArgsBuf) + String(name->data());
  return StringData::GetStaticString(s.get());
}
Example #11
0
bool AutoloadHandler::autoloadType(const String& name) {
  return !m_map.isNull() &&
    loadFromMap(name, s_type, true,
      [] (const String& name) {
        return Unit::GetNamedEntity(name.get())->getCachedTypedef() != nullptr;
      }
    ) != Failure;
}
Example #12
0
Variant invoke_static_method(const String& s, const String& method,
                             const Variant& params, bool fatal /* = true */) {
  HPHP::Class* class_ = Unit::lookupClass(s.get());
  if (class_ == nullptr) {
    o_invoke_failed(s.data(), method.data(), fatal);
    return uninit_null();
  }
  const HPHP::Func* f = class_->lookupMethod(method.get());
  if (f == nullptr || !(f->attrs() & AttrStatic) ||
    (!isContainer(params) && !params.isNull())) {
    o_invoke_failed(s.data(), method.data(), fatal);
    return uninit_null();
  }
  Variant ret;
  g_context->invokeFunc((TypedValue*)&ret, f, params, nullptr, class_);
  return ret;
}
bool HHVM_FUNCTION(class_alias, const String& original, const String& alias,
                                bool autoload /* = true */) {
  auto const origClass =
    autoload ? Unit::loadClass(original.get())
             : Unit::lookupClass(original.get());
  if (!origClass) {
    raise_warning("Class %s not found", original.data());
    return false;
  }
  if (origClass->isBuiltin()) {
    raise_warning(
      "First argument of class_alias() must be a name of user defined class");
    return false;
  }

  return Unit::aliasClass(origClass, alias.get());
}
Example #14
0
APCHandle* APCObject::Construct(ObjectData* objectData, size_t& size) {
  // This function assumes the object and object/array down the tree
  // have no internal references and do not implement the serializable
  // interface.
  assert(!objectData->instanceof(SystemLib::s_SerializableClass));
  assert(!objectData->isCollection() || apcExtension::OptimizeSerialization);

  if (objectData->isCollection() && apcExtension::OptimizeSerialization) {
    return APCCollection::MakeShared(objectData, size, false);
  }

  Array odProps;
  objectData->o_getArray(odProps, false);
  auto const propCount = odProps.size();

  size = sizeof(APCObject) + sizeof(Prop) * propCount;
  auto const apcObj = new (std::malloc(size)) APCObject(objectData, propCount);
  if (!propCount) return apcObj->getHandle();

  auto prop = apcObj->props();
  for (ArrayIter it(odProps); !it.end(); it.next()) {
    Variant key(it.first());
    assert(key.isString());
    const Variant& value = it.secondRef();
    APCHandle *val = nullptr;
    if (!value.isNull()) {
      size_t s = 0;
      val = APCHandle::Create(value, s, false, true, true);
      size += s;
    }

    const String& keySD = key.asCStrRef();

    if (!keySD.empty() && *keySD.data() == '\0') {
      int32_t subLen = keySD.find('\0', 1) + 1;
      String cls = keySD.substr(1, subLen - 2);
      if (cls.size() == 1 && cls[0] == '*') {
        // Protected.
        prop->ctx = nullptr;
      } else {
        // Private.
        prop->ctx = Unit::lookupClass(cls.get());
      }

      prop->name = makeStaticString(keySD.substr(subLen));
    } else {
      prop->ctx = nullptr;
      prop->name = makeStaticString(keySD.get());
    }

    prop->val = val;

    ++prop;
  }
  assert(prop == apcObj->props() + propCount);

  return apcObj->getHandle();
}
Example #15
0
int FuncEmitter::parseNativeAttributes(Attr& attrs_) const {
  int ret = Native::AttrNone;

  auto it = userAttributes.find(s_native.get());
  assert(it != userAttributes.end());
  const TypedValue userAttr = it->second;
  assert(isArrayType(userAttr.m_type));
  for (ArrayIter it(userAttr.m_data.parr); it; ++it) {
    Variant userAttrVal = it.second();
    if (userAttrVal.isString()) {
      String userAttrStrVal = userAttrVal.toString();
      if (userAttrStrVal.get()->isame(s_actrec.get())) {
        ret |= Native::AttrActRec;
        attrs_ |= AttrMayUseVV;
      } else if (userAttrStrVal.get()->isame(s_nofcallbuiltin.get())) {
        attrs_ |= AttrNoFCallBuiltin;
      } else if (userAttrStrVal.get()->isame(s_variadicbyref.get())) {
        attrs_ |= AttrVariadicByRef;
      } else if (userAttrStrVal.get()->isame(s_noinjection.get())) {
        attrs_ |= AttrNoInjection;
      } else if (userAttrStrVal.get()->isame(s_zendcompat.get())) {
        ret |= Native::AttrZendCompat;
        // ZendCompat implies ActRec, no FCallBuiltin
        attrs_ |= AttrMayUseVV | AttrNoFCallBuiltin;
        ret |= Native::AttrActRec;
      } else if (userAttrStrVal.get()->isame(s_numargs.get())) {
        attrs_ |= AttrNumArgs;
      } else if (userAttrStrVal.get()->isame(s_opcodeimpl.get())) {
        ret |= Native::AttrOpCodeImpl;
      }
    }
  }
  return ret;
}
Example #16
0
VarNR::VarNR(const String& v) {
  init(KindOfString);
  StringData *s = v.get();
  if (s) {
    m_data.pstr = s;
  } else {
    m_type = KindOfNull;
  }
}
Example #17
0
void RenamedFuncDict::addRenameableFunctions(ArrayData* arr) {
  m_restrictRenameableFunctions = true;
  for (ArrayIter iter(arr); iter; ++iter) {
    String name = iter.second().toString();
    if (!name.empty()) {
      m_renameableFunctions.insert(name.get());
    }
  }
}
Example #18
0
Variant f_stream_resolve_include_path(const String& filename,
                                     const Resource& context /* = null_object */) {
  struct stat s;
  String ret = Eval::resolveVmInclude(filename.get(), "", &s, true);
  if (ret.isNull()) {
    return false;
  }
  return ret;
}
Example #19
0
	bool XmlUtil::get_bool_property(const xmlNodePtr node,
		const String &property)
	{
		const xmlAttr *attr;

		if (node == 0)
		{
			EL_THROW_EXCEPTION(InvalidParameterException()
				<< errinfo_message(UTF8("parameter is zero"))
				<< errinfo_parameter_name(UTF8("node")));
		}

		for (attr = node->properties; attr; attr = attr->next)
		{
			if ((attr->type == XML_ATTRIBUTE_NODE) &&
				(xmlStrcasecmp(attr->name,
					BAD_CAST property.get().c_str()) == 0))
			{
				if (attr->children == 0)
				{
					return false;
				}

				if (xmlStrcmp(attr->children->content,
					BAD_CAST UTF8("true")) == 0)
				{
					return true;
				}

				if (xmlStrcmp(attr->children->content,
					BAD_CAST UTF8("yes")) == 0)
				{
					return true;
				}

				if (xmlStrcmp(attr->children->content,
					BAD_CAST UTF8("false")) == 0)
				{
					return false;
				}

				if (xmlStrcmp(attr->children->content,
					BAD_CAST UTF8("no")) == 0)
				{
					return false;
				}

				return boost::lexical_cast<bool>(
					attr->children->content);
			}
		}

		EL_THROW_EXCEPTION(ItemNotFoundException()
			<< errinfo_message(UTF8("Property not found"))
			<< errinfo_item_name(property)
			<< errinfo_parameter_name((char*)node->name));
	}
Example #20
0
void mxSetFieldByNumber(mxArray *array_ptr, int lindex, int field_number, mxArray *value)
{
    if (mxIsStruct(array_ptr) && lindex < mxGetNumberOfElements(array_ptr))
    {
        SingleStruct *ptr = ((Struct *)array_ptr)->get(lindex);
        String *names = ptr->getFieldNames();
        ptr->set(names->get(field_number), (InternalType *)value);
    }
}
Example #21
0
void rename_function(const String& old_name, const String& new_name) {
  auto const old = old_name.get();
  auto const n3w = new_name.get();
  auto const oldNe = const_cast<NamedEntity*>(Unit::GetNamedEntity(old));
  auto const newNe = const_cast<NamedEntity*>(Unit::GetNamedEntity(n3w));

  Func* func = Unit::lookupFunc(oldNe);
  if (!func) {
    // It's the caller's responsibility to ensure that the old function
    // exists.
    not_reached();
  }

  // Interceptable functions can be renamed even when
  // JitEnableRenameFunction is false.
  if (!(func->attrs() & AttrInterceptable)) {
    if (!RuntimeOption::EvalJitEnableRenameFunction) {
      // When EvalJitEnableRenameFunction is false, the translator may
      // wire non-AttrInterceptable Func*'s into the TC. Don't rename
      // functions.
      raise_error("fb_rename_function must be explicitly enabled"
                  "(-v Eval.JitEnableRenameFunction=true)");
    }
  }

  auto const fnew = Unit::lookupFunc(newNe);
  if (fnew && fnew != func) {
    // To match hphpc, we silently ignore functions defined in user code that
    // have the same name as a function defined in a separable extension
    if (!fnew->isAllowOverride()) {
      raise_error("Function already defined: %s", n3w->data());
    }
    return;
  }

  always_assert(!RDS::isPersistentHandle(oldNe->getFuncHandle()));
  oldNe->setCachedFunc(nullptr);
  newNe->m_cachedFunc.bind();
  newNe->setCachedFunc(func);

  if (RuntimeOption::EvalJit) {
    JIT::invalidateForRenameFunction(old);
  }
}
Example #22
0
static String memcache_prepare_key(const String& var) {
  auto data = var.get()->mutableData();
  for (int i = 0; i < var.length(); i++) {
    // This is a stupid encoding since it causes collisions but it matches php5
    if (data[i] <= ' ') {
      data[i] = '_';
    }
  }
  return data;
}
Example #23
0
			/**
			 * Writes an utf-8 encoded string. The size is stored
			 * as dynamic uint.
			 * @param str The string to write.
			 */
			inline void write_dynamic_utf8_string(
				const String &str)
			{
				Uint64 size;

				size = str.get().size();

				write_dynamic_uint(size);
				write_utf8_string(str, size);
			}
Example #24
0
Variant invoke(const String& function, CArrRef params, strhash_t hash /* = -1 */,
               bool tryInterp /* = true */, bool fatal /* = true */) {
  Func* func = Unit::loadFunc(function.get());
  if (func) {
    Variant ret;
    g_vmContext->invokeFunc(ret.asTypedValue(), func, params);
    return ret;
  }
  return invoke_failed(function.c_str(), params, fatal);
}
Example #25
0
UserStreamWrapper::UserStreamWrapper(const String& name,
                                     const String& clsname,
                                     int flags)
    : m_name(name) {
  m_cls = Unit::loadClass(clsname.get());
  if (!m_cls) {
    throw InvalidArgumentException(0, "Undefined class '%s'", clsname.data());
  }
  m_isLocal = !(flags & k_STREAM_IS_URL);
}
UserStreamWrapper::UserStreamWrapper(const String& name,
                                     const String& clsname)
    : m_name(name) {
  m_cls = Unit::loadClass(clsname.get());
  if (!m_cls) {
    throw InvalidArgumentException(0, "Undefined class '%s'", clsname.data());
  }
  // There is a third param in Zend to stream_wrapper_register() which could
  // affect that when we add that param
  m_isLocal = true;
}
Example #27
0
Variant invoke(const String& function, const Variant& params,
               strhash_t hash /* = -1 */, bool tryInterp /* = true */,
               bool fatal /* = true */) {
  Func* func = Unit::loadFunc(function.get());
  if (func && (isContainer(params) || params.isNull())) {
    Variant ret;
    g_context->invokeFunc(ret.asTypedValue(), func, params);
    return ret;
  }
  return invoke_failed(function.c_str(), fatal);
}
Example #28
0
bool ConcurrentTableSharedStore::get(const String& key, Variant &value) {
  const StoreValue *sval;
  APCHandle *svar = nullptr;
  ConditionalReadLock l(m_lock, !apcExtension::ConcurrentTableLockFree ||
                                m_lockingFlag);
  bool expired = false;
  bool promoteObj = false;
  {
    Map::const_accessor acc;
    if (!m_vars.find(acc, tagStringData(key.get()))) {
      return false;
    } else {
      sval = &acc->second;
      if (sval->expired()) {
        // Because it only has a read lock on the data, deletion from
        // expiration has to happen after the lock is released
        expired = true;
      } else {
        if (!sval->inMem()) {
          std::lock_guard<SmallLock> sval_lock(sval->lock);

          if (!sval->inMem()) {
            svar = unserialize(key, sval);
            if (!svar) return false;
          } else {
            svar = sval->var;
          }
        } else {
          svar = sval->var;
        }

        if (apcExtension::AllowObj && svar->is(KindOfObject) &&
            !svar->getObjAttempted()) {
          // Hold ref here for later promoting the object
          svar->reference();
          promoteObj = true;
        }
        value = svar->toLocal();
      }
    }
  }
  if (expired) {
    eraseImpl(key, true, apcExtension::UseUncounted ?
                              HPHP::Treadmill::getOldestStartTime() : 0);
    return false;
  }

  if (promoteObj)  {
    handlePromoteObj(key, svar, value);
    // release the extra ref
    svar->unreference();
  }
  return true;
}
Example #29
0
/* called by TypeAliasReq to get resolved TypeStructure for type aliases */
Array TypeStructure::resolve(const String& aliasName,
                             const Array& arr) {
  // use a bogus constant to store the name
  Class::Const cns;
  cns.m_name = aliasName.get();

  auto newarr = resolveTS(arr, cns, nullptr);
  newarr.add(s_alias, Variant(aliasName));
  newarr.setEvalScalar();
  return newarr;
}
Example #30
0
/*
 * Called by TypeAliasReq to get resolved TypeStructure for type aliases.
 */
Array TypeStructure::resolve(const String& aliasName,
                             const Array& arr,
                             bool& persistent,
                             const Array& generics) {
  // use a bogus constant to store the name
  Class::Const cns;
  cns.name = aliasName.get();

  auto newarr = resolveTS(arr, cns, nullptr, generics, persistent);
  newarr.add(s_alias, Variant(aliasName));
  return newarr;
}