Beispiel #1
0
const StringData* PreClass::manglePropName(const StringData* className,
                                           const StringData* propName,
                                           Attr attrs) {
  switch (attrs & (AttrPublic|AttrProtected|AttrPrivate)) {
    case AttrPublic: {
      return propName;
    }
    case AttrProtected: {
      std::string mangledName = "";
      mangledName.push_back('\0');
      mangledName.push_back('*');
      mangledName.push_back('\0');
      mangledName += propName->data();
      return makeStaticString(mangledName);
    }
    case AttrPrivate: {
      std::string mangledName = "";
      mangledName.push_back('\0');
      mangledName += className->data();
      mangledName.push_back('\0');
      mangledName += propName->data();
      return makeStaticString(mangledName);
    }
    default: not_reached();
  }
}
Beispiel #2
0
void StandardExtension::initStandard() {
  // define('HHVM_VERSION_ID', XXYYZZ);
  Native::registerConstant<KindOfInt64>(
    s_HHVM_VERSION_ID.get(),
    ((HHVM_VERSION_MAJOR * 10000) +
     (HHVM_VERSION_MINOR *   100) +
      HHVM_VERSION_PATCH)
  );

  // define('HPHP_VERSION', 'XX.YY.XX')
  // define('HHVM_VERSION', 'XX.YY.XX')
  Native::registerConstant<KindOfPersistentString>(
    s_HHVM_VERSION.get(),
    s_HHVM_VERSION_string.get()
  );
  Native::registerConstant<KindOfPersistentString>(
    s_HPHP_VERSION.get(),
    s_HHVM_VERSION_string.get()
  );

  Native::registerConstant<KindOfBoolean>(
    s_HHVM_DEBUG.get(),
    debug
  );

  Native::registerConstant<KindOfPersistentString>(
    s_HHVM_COMPILER_ID.get(),
    makeStaticString(compilerId())
  );

  Native::registerConstant<KindOfPersistentString>(
    s_HHVM_REPO_SCHEMA.get(),
    makeStaticString(repoSchemaId())
  );
}
Beispiel #3
0
void StandardExtension::initMisc() {
    HHVM_FALIAS(HH\\server_warmup_status, server_warmup_status);
    HHVM_FE(connection_aborted);
    HHVM_FE(connection_status);
    HHVM_FE(connection_timeout);
    HHVM_FE(constant);
    HHVM_FE(define);
    HHVM_FE(defined);
    HHVM_FE(ignore_user_abort);
    HHVM_FE(pack);
    HHVM_FE(sleep);
    HHVM_FE(usleep);
    HHVM_FE(time_nanosleep);
    HHVM_FE(time_sleep_until);
    HHVM_FE(uniqid);
    HHVM_FE(unpack);
    HHVM_FE(sys_getloadavg);
    HHVM_FE(token_get_all);
    HHVM_FE(token_name);
    HHVM_FE(hphp_to_string);
    Native::registerConstant<KindOfDouble>(makeStaticString("INF"), k_INF);
    Native::registerConstant<KindOfDouble>(makeStaticString("NAN"), k_NAN);
    Native::registerConstant<KindOfInt64>(
        makeStaticString("PHP_MAXPATHLEN"), MAXPATHLEN);
    Native::registerConstant<KindOfBoolean>(makeStaticString("PHP_DEBUG"),
      #if DEBUG
        true
      #else
        false
      #endif
     );
    loadSystemlib("std_misc");
  }
Beispiel #4
0
StringData *StringData::getChar(int offset) const {
  if (offset >= 0 && offset < size()) {
    return makeStaticString(m_data[offset]);
  }
  raise_notice("Uninitialized string offset: %d", offset);
  return makeStaticString("");
}
Beispiel #5
0
void TypeConstraint::init() {
  if (UNLIKELY(s_typeNamesToTypes.empty())) {
    const struct Pair {
      const StringData* name;
      Type type;
    } pairs[] = {
      { makeStaticString("HH\\bool"),   { KindOfBoolean, MetaType::Precise }},
      { makeStaticString("HH\\int"),    { KindOfInt64,   MetaType::Precise }},
      { makeStaticString("HH\\float"),  { KindOfDouble,  MetaType::Precise }},
      { makeStaticString("HH\\string"), { KindOfString,  MetaType::Precise }},
      { makeStaticString("array"),      { KindOfArray,   MetaType::Precise }},
      { makeStaticString("HH\\resource"), { KindOfResource,
                                                         MetaType::Precise }},
      { makeStaticString("HH\\num"),    { KindOfDouble,  MetaType::Number }},
      { makeStaticString("self"),       { KindOfObject,  MetaType::Self }},
      { makeStaticString("parent"),     { KindOfObject,  MetaType::Parent }},
      { makeStaticString("callable"),   { KindOfObject,  MetaType::Callable }},
    };
    for (unsigned i = 0; i < sizeof(pairs) / sizeof(Pair); ++i) {
      s_typeNamesToTypes[pairs[i].name] = pairs[i].type;
    }
  }

  if (isTypeVar()) {
    // We kept the type variable type constraint to correctly check child
    // classes implementing abstract methods or interfaces.
    m_type.dt = KindOfInvalid;
    m_type.metatype = MetaType::Precise;
    return;
  }

  if (m_typeName == nullptr) {
    m_type.dt = KindOfInvalid;
    m_type.metatype = MetaType::Precise;
    return;
  }

  Type dtype;
  TRACE(5, "TypeConstraint: this %p type %s, nullable %d\n",
        this, m_typeName->data(), isNullable());
  auto const mptr = folly::get_ptr(s_typeNamesToTypes, m_typeName);
  if (mptr) dtype = *mptr;
  if (!mptr ||
      !(isHHType() || dtype.dt == KindOfArray ||
        dtype.metatype == MetaType::Parent ||
        dtype.metatype == MetaType::Self ||
        dtype.metatype == MetaType::Callable)) {
    TRACE(5, "TypeConstraint: this %p no such type %s, treating as object\n",
          this, m_typeName->data());
    m_type = { KindOfObject, MetaType::Precise };
    m_namedEntity = Unit::GetNamedEntity(m_typeName);
    TRACE(5, "TypeConstraint: NamedEntity: %p\n", m_namedEntity);
    return;
  }
  m_type = dtype;
  assert(m_type.dt != KindOfStaticString);
  assert(IMPLIES(isParent(), m_type.dt == KindOfObject));
  assert(IMPLIES(isSelf(), m_type.dt == KindOfObject));
  assert(IMPLIES(isCallable(), m_type.dt == KindOfObject));
}
Beispiel #6
0
void FuncEmitter::setBuiltinFunc(const ClassInfo::MethodInfo* info,
                                 BuiltinFunction bif, BuiltinFunction nif,
                                 Offset base_) {
  assert(info);
  m_info = info;
  Attr attrs_ = AttrBuiltin;
  if (info->attribute & (ClassInfo::RefVariableArguments |
                         ClassInfo::MixedVariableArguments)) {
    attrs_ |= AttrVariadicByRef;
  }
  if (info->attribute & ClassInfo::IsReference) {
    attrs_ |= AttrReference;
  }
  if (info->attribute & ClassInfo::NoInjection) {
    attrs_ |= AttrNoInjection;
  }
  if (info->attribute & ClassInfo::NoFCallBuiltin) {
    attrs_ |= AttrNoFCallBuiltin;
  }
  if (info->attribute & ClassInfo::ParamCoerceModeNull) {
    attrs_ |= AttrParamCoerceModeNull;
  } else if (info->attribute & ClassInfo::ParamCoerceModeFalse) {
    attrs_ |= AttrParamCoerceModeFalse;
  }
  if (pce()) {
    if (info->attribute & ClassInfo::IsStatic) {
      attrs_ |= AttrStatic;
    }
    if (info->attribute & ClassInfo::IsFinal) {
      attrs_ |= AttrFinal;
    }
    if (info->attribute & ClassInfo::IsAbstract) {
      attrs_ |= AttrAbstract;
    }
    if (info->attribute & ClassInfo::IsPrivate) {
      attrs_ |= AttrPrivate;
    } else if (info->attribute & ClassInfo::IsProtected) {
      attrs_ |= AttrProtected;
    } else {
      attrs_ |= AttrPublic;
    }
  } else if (info->attribute & ClassInfo::AllowOverride) {
    attrs_ |= AttrAllowOverride;
  }

  returnType = info->returnType;
  docComment = makeStaticString(info->docComment);
  setLocation(0, 0);
  setBuiltinFunc(bif, nif, attrs_, base_);

  for (unsigned i = 0; i < info->parameters.size(); ++i) {
    // For builtin only, we use a dummy ParamInfo
    FuncEmitter::ParamInfo pi;
    const auto& parameter = info->parameters[i];
    pi.byRef = parameter->attribute & ClassInfo::IsReference;
    pi.builtinType = parameter->argType;
    appendParam(makeStaticString(parameter->name), pi);
  }
}
Beispiel #7
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();
}
Beispiel #8
0
APCHandle::Pair APCObject::Construct(ObjectData* objectData) {
    // 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));

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

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

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

        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.
                auto* ctx = Unit::lookupClass(cls.get());
                if (ctx && ctx->attrs() & AttrUnique) {
                    prop->ctx = ctx;
                } else {
                    prop->ctx = makeStaticString(cls.get());
                }
            }
            prop->name = makeStaticString(keySD.substr(subLen));
        } else {
            prop->ctx = nullptr;
            prop->name = makeStaticString(keySD.get());
        }
    }
    assert(prop == apcObj->props() + propCount);

    return {apcObj->getHandle(), size};
}
Beispiel #9
0
  void moduleInit() override {
    HHVM_ME(MCRouter, __construct);

    HHVM_NAMED_ME(MCRouter, get,  mcr_str<mc_op_get>);
    HHVM_NAMED_ME(MCRouter, gets, mcr_str<mc_op_gets>);

    HHVM_NAMED_ME(MCRouter, add, mcr_set<mc_op_add>);
    HHVM_NAMED_ME(MCRouter, set, mcr_set<mc_op_set>);
    HHVM_NAMED_ME(MCRouter, replace, mcr_set<mc_op_replace>);
    HHVM_NAMED_ME(MCRouter, prepend, mcr_aprepend<mc_op_prepend>);
    HHVM_NAMED_ME(MCRouter, append, mcr_aprepend<mc_op_append>);

    HHVM_NAMED_ME(MCRouter, incr, mcr_str_delta<mc_op_incr>);
    HHVM_NAMED_ME(MCRouter, decr, mcr_str_delta<mc_op_decr>);

    HHVM_NAMED_ME(MCRouter, del, mcr_str<mc_op_delete>);
    HHVM_NAMED_ME(MCRouter, flushAll, mcr_int<mc_op_flushall>);

    HHVM_NAMED_ME(MCRouter, version, mcr_void<mc_op_version>);

    HHVM_ME(MCRouter, cas);

    Native::registerNativeDataInfo<MCRouter>(s_MCRouter.get());

    HHVM_STATIC_ME(MCRouter, getOpName);
    HHVM_STATIC_ME(MCRouter, getResultName);

    std::string opname("mc_op_");
    for (int i = 0; i < mc_nops; ++i) {
      std::string name;
      name = opname + mc_op_to_string((mc_op_t)i);
      // mcrouter defines op names as foo-bar,
      // but PHP wants constants like foo_bar
      for (int j = opname.size(); j < name.size(); ++j) {
        if (name[j] == '-') {
          name[j] = '_';
        }
      }
      Native::registerClassConstant<KindOfInt64>(
        s_MCRouter.get(),
        makeStaticString(name),
        i);
    }
    for (int i = 0; i < mc_nres; ++i) {
      Native::registerClassConstant<KindOfInt64>(
        s_MCRouter.get(),
        makeStaticString(mc_res_to_string((mc_res_t)i)),
        i);
    }

    loadSystemlib();
  }
Beispiel #10
0
NEVER_INLINE
APCHandle::Pair APCObject::ConstructSlow(ObjectData* objectData,
                                         ClassOrName name) {
  Array odProps;
  objectData->o_getArray(odProps);
  auto const propCount = odProps.size();

  auto size = sizeof(APCObject) + sizeof(Prop) * propCount;
  auto const apcObj = new (malloc_huge(size)) APCObject(name, propCount);
  if (!propCount) return {apcObj->getHandle(), size};

  auto prop = apcObj->props();
  for (ArrayIter it(odProps); !it.end(); it.next(), ++prop) {
    Variant key(it.first());
    assert(key.isString());
    auto const rval = it.secondRval();
    if (!isNullType(tvToCell(rval).type())) {
      auto val = APCHandle::Create(VarNR(rval.tv()), false,
                                   APCHandleLevel::Inner, true);
      prop->val = val.handle;
      size += val.size;
    } else {
      prop->val = nullptr;
    }

    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.
        auto* ctx = Unit::lookupClass(cls.get());
        if (ctx && ctx->attrs() & AttrUnique) {
          prop->ctx = ctx;
        } else {
          prop->ctx = makeStaticString(cls.get());
        }
      }
      prop->name = makeStaticString(keySD.substr(subLen));
    } else {
      prop->ctx = nullptr;
      prop->name = makeStaticString(keySD.get());
    }
  }
  assert(prop == apcObj->props() + propCount);

  return {apcObj->getHandle(), size};
}
Beispiel #11
0
// Ask every thread in this proxy's sandbox and the dummy sandbox to
// "stop".  Gaining control of these threads is the intention... the
// mechanism is to force them all to start interpreting all of their
// code in an effort to gain control in phpDebuggerOpcodeHook(). We
// set the "debugger interrupt" flag to ensure we interpret code
// rather than entering translated code, and we set the "debugger
// signal" surprise flag to pop out of loops in translated code.
void Debugger::requestInterrupt(DebuggerProxyPtr proxy) {
  TRACE(2, "Debugger::requestInterrupt\n");
  const StringData* sid = makeStaticString(proxy->getSandboxId());
  FOREACH_SANDBOX_THREAD_BEGIN(sid, ti)
    ti->m_reqInjectionData.setDebuggerIntr(true);
    ti->m_reqInjectionData.setFlag(DebuggerSignalFlag);
  FOREACH_SANDBOX_THREAD_END()

  sid = makeStaticString(proxy->getDummyInfo().id());
  FOREACH_SANDBOX_THREAD_BEGIN(sid, ti)
    ti->m_reqInjectionData.setDebuggerIntr(true);
    ti->m_reqInjectionData.setFlag(DebuggerSignalFlag);
  FOREACH_SANDBOX_THREAD_END()
}
Beispiel #12
0
// NB: when this returns, the Debugger class no longer has any references to the
// given proxy. It will likely be destroyed when the caller's reference goes out
// of scope.
void Debugger::removeProxy(DebuggerProxyPtr proxy) {
  TRACE(2, "Debugger::removeProxy\n");
  if (proxy->getSandbox().valid()) {
    const StringData* sid = makeStaticString(proxy->getSandboxId());
    setDebuggerFlag(sid, false);
    m_proxyMap.erase(sid);
  }
  const StringData* dummySid =
    makeStaticString(proxy->getDummyInfo().id());
  m_proxyMap.erase(dummySid);
  // Clear the debugger blacklist PC upon last detach if JIT is used
  if (RuntimeOption::EvalJit && countConnectedProxy() == 0) {
    Transl::Translator::Get()->clearDbgBL();
  }
}
Beispiel #13
0
void ZendExtension::moduleInit() {
  if (!RuntimeOption::EnableZendCompat) {
    return;
  }
  // Give it a module number
  zend_module_entry* module = getEntry();
  module->module_number = s_zend_next_module++;
  s_zend_extensions->insert(module->module_number, this);

  ZendObject::registerNativeData();
  // Allocate globals
  if (module->globals_size) {
    ts_allocate_id(module->globals_id_ptr, module->globals_size,
        (ts_allocate_ctor) module->globals_ctor,
        (ts_allocate_dtor) module->globals_dtor);
  }
  // Register global functions
  const zend_function_entry * fe = module->functions;
  while (fe->fname) {
    assert(fe->handler);
    Native::registerBuiltinFunction(makeStaticString(fe->fname),
                                          fe->handler);
    fe++;
  }
  // Call MINIT
  if (module->module_startup_func) {
    TSRMLS_FETCH();
    module->module_startup_func(1, module->module_number TSRMLS_CC);
  }
  // The systemlib name must match the name used by the build process. For
  // in-tree builds this is the directory name, which is typically the same
  // as the extension name converted to lower case.
  std::string slName = toLower(std::string(getName()));
  loadSystemlib(slName);
}
Beispiel #14
0
bool UnitRepoProxy::loadHelper(UnitEmitter& ue,
                               const std::string& name,
                               const MD5& md5) {
  ue.m_filepath = makeStaticString(name);
  // Look for a repo that contains a unit with matching MD5.
  int repoId;
  for (repoId = RepoIdCount - 1; repoId >= 0; --repoId) {
    if (!getUnit[repoId].get(ue, md5)) {
      break;
    }
  }
  if (repoId < 0) {
    TRACE(3, "No repo contains '%s' (0x%016" PRIx64  "%016" PRIx64 ")\n",
             name.c_str(), md5.q[0], md5.q[1]);
    return false;
  }
  try {
    getUnitLitstrs[repoId].get(ue);
    getUnitArrays[repoId].get(ue);
    m_repo.pcrp().getPreClasses[repoId].get(ue);
    getUnitMergeables[repoId].get(ue);
    getUnitLineTable(repoId, ue.m_sn, ue.m_lineTable);
    m_repo.frp().getFuncs[repoId].get(ue);
  } catch (RepoExc& re) {
    TRACE(0,
          "Repo error loading '%s' (0x%016" PRIx64 "%016"
          PRIx64 ") from '%s': %s\n",
          name.c_str(), md5.q[0], md5.q[1], m_repo.repoName(repoId).c_str(),
          re.msg().c_str());
    return false;
  }
  TRACE(3, "Repo loaded '%s' (0x%016" PRIx64 "%016" PRIx64 ") from '%s'\n",
           name.c_str(), md5.q[0], md5.q[1], m_repo.repoName(repoId).c_str());
  return true;
}
Beispiel #15
0
    void moduleLoad(const IniSetting::Map& ini, Hdf config) override {

      // Grab the external entity whitelist and set up the map, then register
      // the callback for external entity loading. data: is always supported
      // since it doesn't reference data outside of the current document.
      std::vector<std::string> whitelist;
      auto whitelistStr = Config::GetString(ini, config,
                                            "Eval.Libxml.ExtEntityWhitelist");
      folly::split(',', whitelistStr, whitelist, true);

      s_ext_entity_whitelist.reserve(1 + whitelist.size());
      s_ext_entity_whitelist.insert(makeStaticString("data"));
      for (auto const& str : whitelist) {
        s_ext_entity_whitelist.insert(makeStaticString(str));
      }
    }
Beispiel #16
0
const char* EventHook::GetFunctionNameForProfiler(const Func* func,
                                                  int funcType) {
  const char* name;
  switch (funcType) {
    case EventHook::NormalFunc:
      name = func->fullName()->data();
      if (name[0] == '\0') {
        // We're evaling some code for internal purposes, most
        // likely getting the default value for a function parameter
        name = "{internal}";
      }
      break;
    case EventHook::PseudoMain:
      name = makeStaticString(
        std::string("run_init::") + func->unit()->filepath()->data())
        ->data();
      break;
    case EventHook::Eval:
      name = "_";
      break;
    default:
      not_reached();
  }
  return name;
}
Beispiel #17
0
void UnitEmitter::initMain(int line1, int line2) {
  assert(m_fes.size() == 0);
  StringData* name = makeStaticString("");
  FuncEmitter* pseudomain = newFuncEmitter(name);
  Attr attrs = AttrMayUseVV;
  pseudomain->init(line1, line2, 0, attrs, false, name);
}
Beispiel #18
0
SSATmp* TraceBuilder::preOptimizeAssertLoc(IRInstruction* inst) {
  auto const locId = inst->extra<AssertLoc>()->locId;

  auto const prevType = localType(locId, DataTypeGeneric);
  auto const typeParam = inst->typeParam();

  if (prevType.not(typeParam)) {
    /* Task #2553746
     * This is triggering for a case where the tracked state says the local is
     * InitNull but the AssertLoc says it's Str. */
    static auto const error =
      makeStaticString("Internal error: static analysis was "
                       "wrong about a local variable's type.");
    auto* errorInst = m_unit.gen(RaiseError, inst->marker(), cns(error));
    inst->become(m_unit, errorInst);

    // It's not a disaster to generate this in unreachable code for
    // now. t2590033.
    if (false) {
      assert_log(false,  [&]{
          return folly::format("\npreOptimizeAssertLoc: prevType: {} "
                               "typeParam: {}\nin instr: {}\nin trace: {}\n",
                               prevType.toString(),
                               typeParam.toString(),
                               inst->toString(),
                               m_unit.main()->toString()).str();
        });
    }
  } else if (shouldElideAssertType(prevType, typeParam, nullptr)) {
    // The type we're asserting is worse than the last known type.
    return inst->src(0);
  }
  return nullptr;
}
Beispiel #19
0
void Variant::setEvalScalar() {
  switch (m_type) {
  case KindOfString: {
    StringData *pstr = m_data.pstr;
    if (!pstr->isStatic()) {
      StringData *sd = makeStaticString(pstr);
      decRefStr(pstr);
      m_data.pstr = sd;
      assert(m_data.pstr->isStatic());
      m_type = KindOfStaticString;
    }
    break;
  }
  case KindOfArray: {
    ArrayData *parr = m_data.parr;
    if (!parr->isStatic()) {
      ArrayData *ad = ArrayData::GetScalarArray(parr);
      decRefArr(parr);
      m_data.parr = ad;
      assert(m_data.parr->isStatic());
    }
    break;
  }
  case KindOfRef:
    not_reached();
    break;
  case KindOfObject:
  case KindOfResource:
    not_reached(); // object shouldn't be in a scalar array
    break;
  default:
    break;
  }
}
Beispiel #20
0
Unit* compile_systemlib_string(const char* s, size_t sz, const char* fname,
                               const Native::FuncTable& nativeFuncs) {
  assertx(fname[0] == '/' && fname[1] == ':');
  if (auto u = lookupSyslibUnit(makeStaticString(fname), nativeFuncs)) {
    return u;
  }
  return compile_string(s, sz, fname, nativeFuncs);
}
Beispiel #21
0
CachedUnit lookupUnitNonRepoAuth(StringData* requestedPath,
                                 const struct stat& statInfo) {
  if (strstr(requestedPath->data(), "://") != nullptr) {
    // URL-based units are not currently cached in memory, but the Repo still
    // caches them on disk.
    return createUnitFromUrl(requestedPath);
  }

  // The string we're using as a key must be static, because we're using it as
  // a key in the cache (across requests).
  auto const path =
    makeStaticString(
      // XXX: it seems weird we have to do this even though we already ran
      // resolveVmInclude.
      (requestedPath->data()[0] == '/'
        ? requestedPath
        : String(SourceRootInfo::GetCurrentSourceRoot()) + StrNR(requestedPath)
      ).get()
    );

  NonRepoUnitCache::accessor acc;
  if (!s_nonRepoUnitCache.insert(acc, path)) {
    if (!isChanged(acc->second, statInfo)) {
      return acc->second.cachedUnit;
    }
  }

  /*
   * NB: the new-unit creation path is here, and is done while holding the tbb
   * lock on s_nonRepoUnitCache.  This was originally done deliberately to
   * avoid wasting time in the compiler (during server startup, many requests
   * hit the same code initial paths that are shared, and would all be
   * compiling the same files).  It's not 100% clear if this is the best way to
   * handle that idea, though (tbb locks spin aggressively and are expected to
   * be low contention).
   */

  /*
   * Don't cache if createNewUnit returns an empty CachedUnit---we'll need to
   * try again anyway if someone tries to load this path, since it might exist
   * later.
   *
   * If there was a unit for this path already, we need to put it on the
   * Treadmill for eventual reclaimation.  We can't delete it immediately
   * because other requests may still be using it.
   */
  auto const cu = createUnitFromFile(path);
  if (auto const oldUnit = acc->second.cachedUnit.unit) {
    Treadmill::enqueue([oldUnit] { reclaimUnit(oldUnit); });
  }
  acc->second.cachedUnit = cu;
  acc->second.mtime      = statInfo.st_mtim;
  acc->second.ino        = statInfo.st_ino;
  acc->second.devId      = statInfo.st_dev;
  return cu;
}
Beispiel #22
0
    void moduleInit() override {
#ifdef USE_EDITLINE
      Native::registerConstant<KindOfStaticString>(
          makeStaticString("READLINE_LIB"), makeStaticString("libedit")
      );
#else
      Native::registerConstant<KindOfStaticString>(
          makeStaticString("READLINE_LIB"), makeStaticString("readline")
      );
#endif
      HHVM_FE(readline);
      HHVM_FE(readline_add_history);
      HHVM_FE(readline_clear_history);
      HHVM_FE(readline_completion_function);
      HHVM_FE(readline_info);
      HHVM_FE(readline_read_history);
      HHVM_FE(readline_write_history);
      loadSystemlib();
    }
Beispiel #23
0
void RepoQuery::getStaticString(int iCol, StringData*& s) {
  if (isNull(iCol)) {
    s = nullptr;
  } else {
    const char* text;
    size_t size;
    getText(iCol, text, size);
    s = makeStaticString(text, size);
  }
}
Beispiel #24
0
Extension::Extension(litstr name, const char *version /* = "" */)
    : m_hhvmAPIVersion(HHVM_API_VERSION)
    , m_name(makeStaticString(name))
    , m_version(version ? version : "") {
  if (s_registered_extensions == NULL) {
    s_registered_extensions = new ExtensionMap();
  }
  assert(s_registered_extensions->find(name) ==
         s_registered_extensions->end());
  (*s_registered_extensions)[name] = this;
}
Beispiel #25
0
// NB: when this returns, the Debugger class no longer has any references to the
// given proxy. It will likely be destroyed when the caller's reference goes out
// of scope.
void Debugger::removeProxy(DebuggerProxyPtr proxy) {
  TRACE(2, "Debugger::removeProxy\n");
  if (proxy->getSandbox().valid()) {
    const StringData* sid = makeStaticString(proxy->getSandboxId());
    setDebuggerFlag(sid, false);
    m_proxyMap.erase(sid);
  }
  const StringData* dummySid =
    makeStaticString(proxy->getDummyInfo().id());
  m_proxyMap.erase(dummySid);
  // Clear the debugger blacklist PC upon last detach if JIT is used
  if (RuntimeOption::EvalJit && countConnectedProxy() == 0) {
    jit::clearDbgBL();
  }

  if (countConnectedProxy() == 0) {
    auto instance = HphpdHook::GetInstance();
    DebuggerHook::setActiveDebuggerInstance(instance, false);
  }
}
Beispiel #26
0
void objOffsetUnset(ObjectData* base, CVarRef offset) {
  objArrayAccess(base);
  static StringData* sd__offsetUnset
    = makeStaticString("offsetUnset");
  assert(!base->isCollection());
  const Func* method = base->methodNamed(sd__offsetUnset);
  assert(method != nullptr);
  TypedValue tv;
  tvWriteUninit(&tv);
  g_vmContext->invokeFuncFew(&tv, method, base, nullptr, 1, offset.asCell());
  tvRefcountedDecRef(&tv);
}
Beispiel #27
0
Id UnitEmitter::mergeUnitLitstr(const StringData* litstr) {
  auto it = m_litstr2id.find(litstr);
  if (it == m_litstr2id.end()) {
    const StringData* str = makeStaticString(litstr);
    Id id = m_litstrs.size();
    m_litstrs.push_back(str);
    m_litstr2id[str] = id;
    return id;
  } else {
    return it->second;
  }
}
Beispiel #28
0
static TypedValue* serialize_vars_helper(ActRec* ar) {
  WddxPacket* wddxPacket = NEWOBJ(WddxPacket)(empty_string_variant_ref,
                                              true, true);
  int start_index = 0;
  for (int i = start_index; i < ar->numArgs(); i++) {
    auto const tv = getArg(ar, i);
    find_var_recursive(tv, wddxPacket);
  }
  const std::string packet = wddxPacket->packet_end();
  Variant strHolder = makeStaticString(packet);
  return arReturn(ar, strHolder);
}
Beispiel #29
0
void Debugger::addOrUpdateSandbox(const DSandboxInfo &sandbox) {
  TRACE(2, "Debugger::addOrUpdateSandbox\n");
  const StringData* sd = makeStaticString(sandbox.id());
  SandboxMap::accessor acc;
  if (m_sandboxMap.insert(acc, sd)) {
    DSandboxInfoPtr sb(new DSandboxInfo());
    *sb = sandbox;
    acc->second = sb;
  } else {
    acc->second->update(sandbox);
  }
}
Beispiel #30
0
  void moduleInit() override {
    Native::registerConstant<KindOfString>(
      s_PCRE_VERSION.get(), makeStaticString(pcre_version())
    );

#define PCRECNS(c) Native::registerConstant<KindOfInt64> \
                    (makeStaticString("PREG_" #c), PHP_PCRE_##c);
    PCRECNS(NO_ERROR);
    PCRECNS(INTERNAL_ERROR);
    PCRECNS(BACKTRACK_LIMIT_ERROR);
    PCRECNS(RECURSION_LIMIT_ERROR);
    PCRECNS(BAD_UTF8_ERROR);
    PCRECNS(BAD_UTF8_OFFSET_ERROR);
#undef PCRECNS
#define PREGCNS(c) Native::registerConstant<KindOfInt64> \
                    (makeStaticString("PREG_" #c), PREG_##c);
    PREGCNS(PATTERN_ORDER);
    PREGCNS(SET_ORDER);
    PREGCNS(OFFSET_CAPTURE);

    PREGCNS(SPLIT_NO_EMPTY);
    PREGCNS(SPLIT_DELIM_CAPTURE);
    PREGCNS(SPLIT_OFFSET_CAPTURE);

    PREGCNS(GREP_INVERT);
#undef PREGCNS

    HHVM_FE(preg_filter);
    HHVM_FE(preg_grep);
    HHVM_FE(preg_match);
    HHVM_FE(preg_match_all);
    HHVM_FE(preg_replace);
    HHVM_FE(preg_replace_callback);
    HHVM_FE(preg_replace_callback_array);
    HHVM_FE(preg_split);
    HHVM_FE(preg_quote);
    HHVM_FE(preg_last_error);
    HHVM_FE(ereg_replace);
    HHVM_FE(eregi_replace);
    HHVM_FE(ereg);
    HHVM_FE(eregi);
    HHVM_FE(split);
    HHVM_FE(spliti);
    HHVM_FE(sql_regcase);

    loadSystemlib();

    pcre_config(PCRE_CONFIG_JIT, &s_pcre_has_jit);
    IniSetting::Bind(this, IniSetting::PHP_INI_ONLY,
                     "hhvm.pcre.jit",
                     &s_pcre_has_jit);
  }