void FiberReferenceMap::unmarshal(Variant &dest, CVarRef src, char strategy) { if (dest.isArray() && src.isArray()) { switch (strategy) { case FiberAsyncFunc::GlobalStateIgnore: // do nothing break; case FiberAsyncFunc::GlobalStateOverwrite: if (src.isInitialized()) { dest = src.fiberUnmarshal(*this); } break; case FiberAsyncFunc::GlobalStateSkip: { Array arr = dest.toArray(); for (ArrayIter iter(src); iter; ++iter) { Variant key = iter.first(); if (!arr.exists(key)) { dest.set(key.fiberUnmarshal(*this), ref(iter.secondRef().fiberUnmarshal(*this))); } } break; } default: raise_error("unknown strategy: %d", (int)strategy); break; } } else if (strategy != FiberAsyncFunc::GlobalStateIgnore) { if (src.isInitialized()) { dest = src.fiberUnmarshal(*this); } } }
static Variant HHVM_STATIC_METHOD(IntlTimeZone, createTimeZoneIDEnumeration, int64_t zoneType, const String& region, CVarRef offset) { if (zoneType != UCAL_ZONE_TYPE_ANY && zoneType != UCAL_ZONE_TYPE_CANONICAL && zoneType != UCAL_ZONE_TYPE_CANONICAL_LOCATION) { s_intl_error->set(U_ILLEGAL_ARGUMENT_ERROR, "intltz_create_time_zone_id_enumeration: bad zone type"); return false; } int32_t *pofs = nullptr; int32_t ofs = 0; if (offset.isInitialized()) { ofs = offset.toInt64(); pofs = &ofs; } UErrorCode error = U_ZERO_ERROR; auto se = icu::TimeZone::createTimeZoneIDEnumeration( (USystemTimeZoneType)zoneType, region.c_str(), pofs, error); if (U_FAILURE(error)) { s_intl_error->set(error, "intltz_create_time_zone_id_enumeration: " "Error obtaining time zone id enumeration"); return false; } return IntlIterator::newInstance(se); }
Variant f_get_parent_class(CVarRef object /* = null_variant */) { if (hhvm) { if (!object.isInitialized()) { CallerFrame cf; HPHP::VM::Class* cls = arGetContextClass(cf()); if (cls && cls->parent()) { return CStrRef(cls->parentRef()); } return false; } } Variant class_name; if (object.isObject()) { class_name = f_get_class(object); } else if (object.isString()) { class_name = object; } else { return false; } const ClassInfo *classInfo = ClassInfo::FindClass(class_name.toString()); if (classInfo) { CStrRef parentClass = classInfo->getParentClass(); if (!parentClass.empty()) { return parentClass; } } return false; }
Variant f_get_parent_class(CVarRef object /* = null_variant */) { if (!object.isInitialized()) { CallerFrame cf; Class* cls = arGetContextClass(cf()); if (cls && cls->parent()) { return String(cls->parentRef()); } return false; } Variant class_name; if (object.isObject()) { class_name = f_get_class(object); } else if (object.isString()) { class_name = object; } else { return false; } const Class* cls = Unit::lookupClass(class_name.toString().get()); if (cls) { auto& parentClass = *(const String*)(&cls->parentRef()); if (!parentClass.empty()) { return parentClass; } } return false; }
void EvalObjectData::o_getArray(Array &props) const { String zero("\0", 1, AttachLiteral); for (ArrayIter it(m_privates); !it.end(); it.next()) { String prefix(zero); prefix += it.first(); prefix += zero; for (ArrayIter it2(it.second()); !it2.end(); it2.next()) { CVarRef v = it2.secondRef(); if (v.isInitialized()) { props.set(prefix + it2.first(), v.isReferenced() ? ref(v) : v); } } } DynamicObjectData::o_getArray(props); }
bool f_stream_context_set_option(CVarRef stream_or_context, CVarRef wrapper_or_options, CVarRef option /* = null_variant */, CVarRef value /* = null_variant */) { StreamContext* context = get_stream_context(stream_or_context); if (!context) { raise_warning("Invalid stream/context parameter"); return false; } if (wrapper_or_options.isArray() && !option.isInitialized() && !value.isInitialized()) { return f_stream_context_set_option0(context, wrapper_or_options.toArray()); } else if (wrapper_or_options.isString() && option.isInitialized() && option.isString() && value.isInitialized()) { return f_stream_context_set_option1(context, wrapper_or_options.toString(), option.toString(), value); } else { raise_warning("called with wrong number or type of parameters; please RTM"); return false; } }
Array Array::keys(CVarRef search_value /* = null_variant */, bool strict /* = false */) const { if (!search_value.isInitialized()) { ArrayInit ai(size(), ArrayInit::vectorInit); for (ArrayIter iter(*this); iter; ++iter) { ai.set(iter.first()); } return ai.create(); } else { Array ret = Array::Create(); for (ArrayIter iter(*this); iter; ++iter) { if ((strict && iter.secondRef().same(search_value)) || (!strict && iter.secondRef().equal(search_value))) { ret.append(iter.first()); } } return ret; } }
static Variant arrayKeysSetHelper(const Cell& cell_input, CVarRef search_value, bool strict) { ArrayIter iter(cell_input); if (LIKELY(!search_value.isInitialized())) { PackedArrayInit ai(getContainerSize(cell_input)); for (; iter; ++iter) { ai.append(iter.second()); } return ai.toArray(); } Array ai = HphpArray::MakeReserve(0); for (; iter; ++iter) { if ((strict && HPHP::same(iter.secondRefPlus(), search_value)) || (!strict && HPHP::equal(iter.secondRefPlus(), search_value))) { ai.append(iter.second()); } } return ai; }
void EvalObjectData::o_getArray(Array &props, bool pubOnly /* = false */) const { if (!pubOnly) { String zero("\0", 1, AttachLiteral); for (ArrayIter it(m_privates); !it.end(); it.next()) { String prefix(zero); prefix += it.first(); prefix += zero; for (ArrayIter it2(it.second()); !it2.end(); it2.next()) { CVarRef v = it2.secondRef(); if (v.isInitialized()) { props.lvalAt(prefix + it2.first()).setWithRef(v); } } } } DynamicObjectData::o_getArray(props, pubOnly); if (pubOnly) { const ClassInfo *info = ClassInfo::FindClass(o_getClassName()); info->filterProperties(props, ClassInfo::IsProtected); } }
Variant f_array_keys(CVarRef input, CVarRef search_value /* = null_variant */, bool strict /* = false */) { const auto& cell_input = *input.asCell(); if (UNLIKELY(!isContainer(cell_input))) { goto warn; } { // We treat Sets differently. For Sets, we pretend the values are // also the keys (similar to how Set::toArray() behaves). bool isSetType = cell_input.m_type == KindOfObject && cell_input.m_data.pobj->getCollectionType() == Collection::SetType; if (UNLIKELY(isSetType)) { return arrayKeysSetHelper(cell_input, search_value, strict); } ArrayIter iter(cell_input); if (LIKELY(!search_value.isInitialized())) { PackedArrayInit ai(getContainerSize(cell_input)); for (; iter; ++iter) { ai.append(iter.first()); } return ai.toArray(); } Array ai = Array::attach(HphpArray::MakeReserve(0)); for (; iter; ++iter) { if ((strict && HPHP::same(iter.secondRefPlus(), search_value)) || (!strict && HPHP::equal(iter.secondRefPlus(), search_value))) { ai.append(iter.first()); } } return ai; } warn: raise_warning("array_keys() expects parameter 1 to be an array " "or collection"); return uninit_null(); }
bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) { if (Loaded) return true; Loaded = true; // load extension functions first, so system/classes may call them ParseExtFunctions(ar, ExtensionFunctions, false); AnalysisResultPtr ar2 = AnalysisResultPtr(new AnalysisResult()); s_variables = VariableTablePtr(new VariableTable(*ar2.get())); s_constants = ConstantTablePtr(new ConstantTable(*ar2.get())); // parse all PHP files under system/classes if (!extOnly) { ar = AnalysisResultPtr(new AnalysisResult()); ar->loadBuiltinFunctions(); string slib = systemlib_path(); if (slib.empty()) { for (const char **cls = SystemClasses; *cls; cls++) { string phpBaseName = "/system/classes/"; phpBaseName += *cls; phpBaseName += ".php"; Parse(ar, phpBaseName, Option::GetSystemRoot() + phpBaseName); } } else { Parse(ar, slib, slib); } ar->analyzeProgram(true); ar->inferTypes(); const StringToFileScopePtrMap &files = ar->getAllFiles(); for (StringToFileScopePtrMap::const_iterator iterFile = files.begin(); iterFile != files.end(); iterFile++) { const StringToClassScopePtrVecMap &classes = iterFile->second->getClasses(); for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin(); iter != classes.end(); ++iter) { assert(iter->second.size() == 1); iter->second[0]->setSystem(); assert(!s_classes[iter->first]); s_classes[iter->first] = iter->second[0]; } } } else { NoSuperGlobals = true; } // load extension constants, classes and dynamics ParseExtConsts(ar, ExtensionConsts, false); ParseExtClasses(ar, ExtensionClasses, false); for (unsigned int i = 0; i < Option::SepExtensions.size(); i++) { Option::SepExtensionOptions &options = Option::SepExtensions[i]; string soname = options.soname; if (soname.empty()) { soname = string("lib") + options.name + ".so"; } if (!options.lib_path.empty()) { soname = options.lib_path + "/" + soname; } if (!LoadSepExtensionSymbols(ar, options.name, soname)) { return false; } } if (!extOnly) { Array constants = ClassInfo::GetSystemConstants(); LocationPtr loc(new Location); for (ArrayIter it = constants.begin(); it; ++it) { CVarRef key = it.first(); if (!key.isString()) continue; std::string name = key.toCStrRef().data(); if (s_constants->getSymbol(name)) continue; if (name == "true" || name == "false" || name == "null") continue; CVarRef value = it.secondRef(); if (!value.isInitialized() || value.isObject()) continue; ExpressionPtr e = Expression::MakeScalarExpression(ar2, ar2, loc, value); TypePtr t = value.isNull() ? Type::Null : value.isBoolean() ? Type::Boolean : value.isInteger() ? Type::Int64 : value.isDouble() ? Type::Double : value.isArray() ? Type::Array : Type::Variant; s_constants->add(key.toCStrRef().data(), t, e, ar2, e); } s_variables = ar2->getVariables(); for (int i = 0, n = NumGlobalNames(); i < n; ++i) { s_variables->add(GlobalNames[i], Type::Variant, false, ar, ConstructPtr(), ModifierExpressionPtr()); } } s_constants->setDynamic(ar, "SID", true); return true; }
bool BuiltinSymbols::Load(AnalysisResultPtr ar) { if (Loaded) return true; Loaded = true; if (g_context.isNull()) init_thread_locals(); ClassInfo::Load(); // load extension functions first, so system/php may call them ImportExtFunctions(ar, ClassInfo::GetSystem()); ConstantTablePtr cns = ar->getConstants(); // load extension constants, classes and dynamics ImportNativeConstants(ar, cns); ImportExtConstants(ar, cns, ClassInfo::GetSystem()); ImportExtClasses(ar); Array constants = ClassInfo::GetSystemConstants(); LocationPtr loc(new Location); for (ArrayIter it = constants.begin(); it; ++it) { CVarRef key = it.first(); if (!key.isString()) continue; std::string name = key.toCStrRef().data(); if (cns->getSymbol(name)) continue; if (name == "true" || name == "false" || name == "null") continue; CVarRef value = it.secondRef(); if (!value.isInitialized() || value.isObject()) continue; ExpressionPtr e = Expression::MakeScalarExpression(ar, ar, loc, value); TypePtr t = value.isNull() ? Type::Null : value.isBoolean() ? Type::Boolean : value.isInteger() ? Type::Int64 : value.isDouble() ? Type::Double : value.isArray() ? Type::Array : Type::Variant; cns->add(key.toCStrRef().data(), t, e, ar, e); } for (int i = 0, n = NumGlobalNames(); i < n; ++i) { ar->getVariables()->add(GlobalNames[i], Type::Variant, false, ar, ConstructPtr(), ModifierExpressionPtr()); } cns->setDynamic(ar, "PHP_BINARY", true); cns->setDynamic(ar, "PHP_BINDIR", true); cns->setDynamic(ar, "PHP_OS", true); cns->setDynamic(ar, "PHP_SAPI", true); cns->setDynamic(ar, "SID", true); // Systemlib files were all parsed by hphp_process_init const StringToFileScopePtrMap &files = ar->getAllFiles(); for (const auto& file : files) { file.second->setSystem(); const auto& classes = file.second->getClasses(); for (const auto& clsVec : classes) { assert(clsVec.second.size() == 1); auto cls = clsVec.second[0]; cls->setSystem(); ar->addSystemClass(cls); for (const auto& func : cls->getFunctions()) { FunctionScope::RecordFunctionInfo(func.first, func.second); } } const auto& functions = file.second->getFunctions(); for (const auto& func : functions) { func.second->setSystem(); ar->addSystemFunction(func.second); FunctionScope::RecordFunctionInfo(func.first, func.second); } } return true; }
bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) { if (Loaded) return true; Loaded = true; if (g_context.isNull()) init_thread_locals(); ClassInfo::Load(); // load extension functions first, so system/classes may call them ImportExtFunctions(ar, s_functions, ClassInfo::GetSystem()); AnalysisResultPtr ar2 = AnalysisResultPtr(new AnalysisResult()); s_variables = VariableTablePtr(new VariableTable(*ar2.get())); s_constants = ConstantTablePtr(new ConstantTable(*ar2.get())); // parse all PHP files under system/classes if (!extOnly) { ar = AnalysisResultPtr(new AnalysisResult()); ar->loadBuiltinFunctions(); string slib = get_systemlib(); Scanner scanner(slib.c_str(), slib.size(), Option::ScannerType, "systemlib.php"); Compiler::Parser parser(scanner, "systemlib.php", ar); if (!parser.parse()) { Logger::Error("Unable to parse systemlib.php: %s", parser.getMessage().c_str()); assert(false); } ar->analyzeProgram(true); ar->inferTypes(); const StringToFileScopePtrMap &files = ar->getAllFiles(); for (StringToFileScopePtrMap::const_iterator iterFile = files.begin(); iterFile != files.end(); iterFile++) { const StringToClassScopePtrVecMap &classes = iterFile->second->getClasses(); for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin(); iter != classes.end(); ++iter) { assert(iter->second.size() == 1); iter->second[0]->setSystem(); assert(!s_classes[iter->first]); s_classes[iter->first] = iter->second[0]; } } } else { NoSuperGlobals = true; } // load extension constants, classes and dynamics ImportExtConstants(ar, s_constants, ClassInfo::GetSystem()); ImportExtClasses(ar); if (!extOnly) { Array constants = ClassInfo::GetSystemConstants(); LocationPtr loc(new Location); for (ArrayIter it = constants.begin(); it; ++it) { CVarRef key = it.first(); if (!key.isString()) continue; std::string name = key.toCStrRef().data(); if (s_constants->getSymbol(name)) continue; if (name == "true" || name == "false" || name == "null") continue; CVarRef value = it.secondRef(); if (!value.isInitialized() || value.isObject()) continue; ExpressionPtr e = Expression::MakeScalarExpression(ar2, ar2, loc, value); TypePtr t = value.isNull() ? Type::Null : value.isBoolean() ? Type::Boolean : value.isInteger() ? Type::Int64 : value.isDouble() ? Type::Double : value.isArray() ? Type::Array : Type::Variant; s_constants->add(key.toCStrRef().data(), t, e, ar2, e); } s_variables = ar2->getVariables(); for (int i = 0, n = NumGlobalNames(); i < n; ++i) { s_variables->add(GlobalNames[i], Type::Variant, false, ar, ConstructPtr(), ModifierExpressionPtr()); } } s_constants->setDynamic(ar, "SID", true); return true; }
void FiberReferenceMap::marshal(Variant &dest, CVarRef src) { if (src.isInitialized()) { dest = src.fiberMarshal(*this); } }