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); }
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(); }
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; }
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; }
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; }
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); }
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()); }
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()); }
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)); }
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()); }
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; }
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()); }
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(); }
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; }
VarNR::VarNR(const String& v) { init(KindOfString); StringData *s = v.get(); if (s) { m_data.pstr = s; } else { m_type = KindOfNull; } }
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()); } } }
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; }
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)); }
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); } }
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); } }
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; }
/** * 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); }
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); }
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; }
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); }
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; }
/* 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; }
/* * 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; }