String HHVM_FUNCTION(exec, const String& command, VRefParam output /* = null */, VRefParam return_var /* = null */) { ShellExecContext ctx; FILE *fp = ctx.exec(command); if (!fp) return empty_string(); StringBuffer sbuf; sbuf.read(fp); Array lines = StringUtil::Explode(sbuf.detach(), "\n").toArray(); int ret = ctx.exit(); if (WIFEXITED(ret)) ret = WEXITSTATUS(ret); return_var = ret; int count = lines.size(); if (count > 0 && lines[count - 1].toString().empty()) { count--; // remove explode()'s last empty line } PackedArrayInit pai(count); for (int i = 0; i < count; i++) { pai.append(lines[i]); } output.wrapped() = pai.toArray(); if (!count || lines.empty()) { return String(); } return HHVM_FN(rtrim)(lines[count - 1].toString()); }
ALWAYS_INLINE static int64_t extract_impl(VRefParam vref_array, int extract_type /* = EXTR_OVERWRITE */, const String& prefix /* = "" */) { bool reference = extract_type & EXTR_REFS; extract_type &= ~EXTR_REFS; if (!vref_array.wrapped().isArray()) { raise_warning("extract() expects parameter 1 to be array"); return 0; } VMRegAnchor _; auto const varEnv = g_context->getVarEnv(); if (!varEnv) return 0; if (UNLIKELY(reference)) { auto& arr = vref_array.wrapped().toArrRef(); int count = 0; for (ArrayIter iter(arr); iter; ++iter) { String name = iter.first(); if (!modify_extract_name(varEnv, name, extract_type, prefix)) continue; g_context->bindVar(name.get(), arr.lvalAt(name).asTypedValue()); ++count; } return count; } auto const var_array = vref_array.wrapped().toArray(); int count = 0; for (ArrayIter iter(var_array); iter; ++iter) { String name = iter.first(); if (!modify_extract_name(varEnv, name, extract_type, prefix)) continue; g_context->setVar(name.get(), iter.secondRef().asTypedValue()); ++count; } return count; }
Variant f_array_push(int _argc, VRefParam array, CVarRef var, CArrRef _argv /* = null_array */) { auto const array_cell = array.wrapped().asCell(); if (UNLIKELY(array_cell->m_type != KindOfArray)) { throw_bad_array_exception(); return uninit_null(); } /* * Important note: this *must* cast the parr in the inner cell to * the Array&---we can't copy it to the stack or anything because we * might escalate. */ Array& arr_array = *reinterpret_cast<Array*>(&array_cell->m_data.parr); arr_array.append(var); for (ArrayIter iter(_argv); iter; ++iter) { arr_array.append(iter.second()); } return arr_array.size(); }
bool HHVM_FUNCTION(is_callable, const Variant& v, bool syntax /* = false */, VRefParam name /* = null */) { return is_callable(v, syntax, name.isReferenced() ? name.wrapped().asTypedValue()->m_data.pref : nullptr); }
ALWAYS_INLINE static int64_t extract_impl(VRefParam vref_array, int extract_type /* = EXTR_OVERWRITE */, const String& prefix /* = "" */) { auto arrByRef = false; auto arr_tv = vref_array.wrapped().asTypedValue(); if (arr_tv->m_type == KindOfRef) { arr_tv = arr_tv->m_data.pref->tv(); arrByRef = true; } if (!isArrayType(arr_tv->m_type)) { raise_warning("extract() expects parameter 1 to be array"); return 0; } bool reference = extract_type & EXTR_REFS; extract_type &= ~EXTR_REFS; VMRegAnchor _; auto const varEnv = g_context->getOrCreateVarEnv(); if (!varEnv) return 0; auto& carr = tvAsCVarRef(arr_tv).asCArrRef(); if (UNLIKELY(reference)) { auto extr_refs = [&](Array& arr) { if (arr.size() > 0) { // force arr to escalate (if necessary) by getting an lvalue to the // first element. ArrayData* ad = arr.get(); auto const& first_key = ad->getKey(ad->iter_begin()); arr.lvalAt(first_key); } int count = 0; for (ArrayIter iter(arr); iter; ++iter) { auto name = iter.first().toString(); if (!modify_extract_name(varEnv, name, extract_type, prefix)) continue; // The const_cast is safe because we escalated the array. We can't use // arr.lvalAt(name), because arr may have been modified as a side // effect of an earlier iteration. auto& ref = const_cast<Variant&>(iter.secondRef()); g_context->bindVar(name.get(), ref.asTypedValue()); ++count; } return count; }; if (arrByRef) { return extr_refs(tvAsVariant(vref_array.getRefData()->tv()).asArrRef()); } Array tmp = carr; return extr_refs(tmp); } int count = 0; for (ArrayIter iter(carr); iter; ++iter) { auto name = iter.first().toString(); if (!modify_extract_name(varEnv, name, extract_type, prefix)) continue; g_context->setVar(name.get(), iter.secondRef().asTypedValue()); ++count; } return count; }