예제 #1
0
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);
    }
  }
}
예제 #2
0
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);
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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);
}
예제 #6
0
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;
  }
}
예제 #7
0
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;
  }
}
예제 #8
0
파일: ext_array.cpp 프로젝트: barkinet/hhvm
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;
}
예제 #9
0
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);
    }
}
예제 #10
0
파일: ext_array.cpp 프로젝트: barkinet/hhvm
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();
}
예제 #11
0
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;
}
예제 #12
0
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;
}
예제 #13
0
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;
}
예제 #14
0
void FiberReferenceMap::marshal(Variant &dest, CVarRef src) {
  if (src.isInitialized()) {
    dest = src.fiberMarshal(*this);
  }
}