Example #1
0
void ProcessInit() {
  // Create the global mcg object
  jit::mcg = new jit::MCGenerator();
  jit::mcg->initUniqueStubs();

  // Save the current options, and set things up so that
  // systemlib.php can be read from and stored in the
  // normal repo.
  int db = RuntimeOption::EvalDumpBytecode;
  bool rp = RuntimeOption::AlwaysUseRelativePath;
  bool sf = RuntimeOption::SafeFileAccess;
  bool ah = RuntimeOption::EvalAllowHhas;
  bool wp = Option::WholeProgram;
  RuntimeOption::EvalDumpBytecode &= ~1;
  RuntimeOption::AlwaysUseRelativePath = false;
  RuntimeOption::SafeFileAccess = false;
  RuntimeOption::EvalAllowHhas = true;
  Option::WholeProgram = false;

  RDS::requestInit();
  string hhas;
  string slib = get_systemlib(&hhas);

  if (slib.empty()) {
    // Die a horrible death.
    Logger::Error("Unable to find/load systemlib.php");
    _exit(1);
  }

  LitstrTable::init();
  LitstrTable::get().setWriting();
  Repo::get().loadGlobalData();

  // Save this in case the debugger needs it. Once we know if this
  // process does not have debugger support, we'll clear it.
  SystemLib::s_source = slib;

  SystemLib::s_unit = compile_systemlib_string(slib.c_str(), slib.size(),
                                               "systemlib.php");

  const StringData* msg;
  int line;
  if (SystemLib::s_unit->compileTimeFatal(msg, line)) {
    Logger::Error("An error has been introduced into the systemlib, "
                  "but we cannot give you a file and line number right now.");
    Logger::Error("Check all of your changes to hphp/system/php");
    Logger::Error("HipHop Parse Error: %s", msg->data());
    _exit(1);
  }

  if (!hhas.empty()) {
    SystemLib::s_hhas_unit = compile_string(hhas.c_str(), hhas.size(),
                                            "systemlib.hhas");
    if (SystemLib::s_hhas_unit->compileTimeFatal(msg, line)) {
      Logger::Error("An error has been introduced in the hhas portion of "
                    "systemlib.");
      Logger::Error("Check all of your changes to hhas files in "
                    "hphp/system/php");
      Logger::Error("HipHop Parse Error: %s", msg->data());
      _exit(1);
    }
  }

  // Load the systemlib unit to build the Class objects
  SystemLib::s_unit->merge();
  if (SystemLib::s_hhas_unit) {
    SystemLib::s_hhas_unit->merge();
  }

  SystemLib::s_nativeFuncUnit = build_native_func_unit(hhbc_ext_funcs,
                                                       hhbc_ext_funcs_count);
  SystemLib::s_nativeFuncUnit->merge();
  SystemLib::s_nullFunc =
    Unit::lookupFunc(makeStaticString("86null"));

  // We call a special bytecode emitter function to build the native
  // unit which will contain all of our cppext functions and classes.
  // Each function and method will have a bytecode body that will thunk
  // to the native implementation.
  Unit* nativeClassUnit = build_native_class_unit(hhbc_ext_classes,
                                                  hhbc_ext_class_count);
  SystemLib::s_nativeClassUnit = nativeClassUnit;

  LitstrTable::get().setReading();

  // Load the nativelib unit to build the Class objects
  SystemLib::s_nativeClassUnit->merge();

#define INIT_SYSTEMLIB_CLASS_FIELD(cls)                                 \
  {                                                                     \
    Class *cls = NamedEntity::get(s_##cls.get())->clsList();       \
    assert(!hhbc_ext_class_count || cls);                               \
    SystemLib::s_##cls##Class = cls;                                    \
  }

  // Stash a pointer to the VM Classes for stdclass, Exception,
  // pinitSentinel and resource
  SYSTEMLIB_CLASSES(INIT_SYSTEMLIB_CLASS_FIELD)

#undef INIT_SYSTEMLIB_CLASS_FIELD

  // Retrieve all of the class pointers
  for (long long i = 0; i < hhbc_ext_class_count; ++i) {
    const HhbcExtClassInfo* info = hhbc_ext_classes + i;
    const StringData* name = makeStaticString(info->m_name);
    const NamedEntity* ne = NamedEntity::get(name);
    Class* cls = Unit::lookupClass(ne);
    assert(cls);
    *(info->m_clsPtr) = cls;
  }

  ClassInfo::InitializeSystemConstants();
  Stack::ValidateStackSize();
  SystemLib::s_inited = true;

  RuntimeOption::AlwaysUseRelativePath = rp;
  RuntimeOption::SafeFileAccess = sf;
  RuntimeOption::EvalDumpBytecode = db;
  RuntimeOption::EvalAllowHhas = ah;
  Option::WholeProgram = wp;

  folly::SingletonVault::singleton()->registrationComplete();
}
Example #2
0
void ProcessInit() {
  // Install VM's ClassInfoHook
  ClassInfo::SetHook(&vm_class_info_hook);

  // ensure that nextTx64 and tx64 are set
  (void)Transl::Translator::Get();

  // Save the current options, and set things up so that
  // systemlib.php can be read from and stored in the
  // normal repo.
  int db = RuntimeOption::EvalDumpBytecode;
  bool rp = RuntimeOption::AlwaysUseRelativePath;
  bool sf = RuntimeOption::SafeFileAccess;
  bool ah = RuntimeOption::EvalAllowHhas;
  RuntimeOption::EvalDumpBytecode &= ~1;
  RuntimeOption::AlwaysUseRelativePath = false;
  RuntimeOption::SafeFileAccess = false;
  RuntimeOption::EvalAllowHhas = true;

  Transl::TargetCache::requestInit();
  string hhas;
  string slib = get_systemlib(&hhas);

  if (slib.empty()) {
    // Die a horrible death.
    Logger::Error("Unable to find/load systemlib.php");
    _exit(1);
  }
  // Save this in case the debugger needs it. Once we know if this
  // process does not have debugger support, we'll clear it.
  SystemLib::s_source = slib;

  SystemLib::s_unit = compile_string(slib.c_str(), slib.size(),
                                     "systemlib.php");
  if (!hhas.empty()) {
    SystemLib::s_hhas_unit = compile_string(hhas.c_str(), hhas.size(),
                                            "systemlib.hhas");
  }

  // Load the systemlib unit to build the Class objects
  SystemLib::s_unit->merge();
  if (SystemLib::s_hhas_unit) {
    SystemLib::s_hhas_unit->merge();
  }

  SystemLib::s_nativeFuncUnit = build_native_func_unit(hhbc_ext_funcs,
                                                       hhbc_ext_funcs_count);
  SystemLib::s_nativeFuncUnit->merge();
  SystemLib::s_nullFunc =
    Unit::lookupFunc(makeStaticString("86null"));

  // We call a special bytecode emitter function to build the native
  // unit which will contain all of our cppext functions and classes.
  // Each function and method will have a bytecode body that will thunk
  // to the native implementation.
  Unit* nativeClassUnit = build_native_class_unit(hhbc_ext_classes,
                                                  hhbc_ext_class_count);
  SystemLib::s_nativeClassUnit = nativeClassUnit;

  // Load the nativelib unit to build the Class objects
  SystemLib::s_nativeClassUnit->merge();

#define INIT_SYSTEMLIB_CLASS_FIELD(cls)                                 \
  {                                                                     \
    Class *cls = Unit::GetNamedEntity(s_##cls.get())->clsList();       \
    assert(!hhbc_ext_class_count || cls);                               \
    SystemLib::s_##cls##Class = cls;                                    \
  }

  // Stash a pointer to the VM Classes for stdclass, Exception,
  // pinitSentinel and resource
  SYSTEMLIB_CLASSES(INIT_SYSTEMLIB_CLASS_FIELD)

#undef INIT_SYSTEMLIB_CLASS_FIELD

  // Retrieve all of the class pointers
  for (long long i = 0; i < hhbc_ext_class_count; ++i) {
    const HhbcExtClassInfo* info = hhbc_ext_classes + i;
    const StringData* name = makeStaticString(info->m_name);
    const NamedEntity* ne = Unit::GetNamedEntity(name);
    Class* cls = Unit::lookupClass(ne);
    assert(cls);
    *(info->m_clsPtr) = cls;
  }

  ClassInfo::InitializeSystemConstants();
  Stack::ValidateStackSize();
  SystemLib::s_inited = true;

  RuntimeOption::AlwaysUseRelativePath = rp;
  RuntimeOption::SafeFileAccess = sf;
  RuntimeOption::EvalDumpBytecode = db;
  RuntimeOption::EvalAllowHhas = ah;
}
Example #3
0
void ProcessInit() {
  // Initialize compiler state
  VM::compile_file(0, 0, MD5(), 0);
  // Install VM's ClassInfoHook
  ClassInfo::SetHook(&vm_class_info_hook);
  VM::Transl::Translator::Get()->processInit();

  Transl::TargetCache::requestInit();

  Unit* nativeFuncUnit = build_native_func_unit(hhbc_ext_funcs,
                                                hhbc_ext_funcs_count);
  SystemLib::s_nativeFuncUnit = nativeFuncUnit;

  // Search for systemlib.php in the following places:
  // 1) ${HHVM_LIB_PATH}/systemlib.php
  // 2) <dirname(realpath(hhvm))>/systemlib.php (requires proc filesystem)
  // 3) ${HPHP_LIB}/systemlib.php
  // 4) <HHVM_LIB_PATH_DEFAULT>/systemlib.php
  //
  // HHVM_LIB_PATH allows a manual override at runtime. If systemlib.php
  // exists next to the hhvm binary, that is likely to be the next best
  // version to use. The realpath()-based lookup will succeed as long as the
  // proc filesystem exists (e.g. on Linux and some FreeBSD configurations)
  // and no hard links are in use for the executable. Under certain build
  // situations, systemlib.php will not be generated next to hhvm binary, so
  // ${HPHP_LIB} is checked next. Failing all of those options, the
  // HHVM_LIB_PATH_DEFAULT-based lookup will always succeed, assuming that the
  // application was built and installed correctly.
  String currentDir = g_vmContext->getCwd();
  HPHP::Eval::PhpFile* file = NULL;

#define SYSTEMLIB_PHP "/systemlib.php"
#define LOOKUP_STR(s) do {                                                    \
  String systemlibPath = String(s) + SYSTEMLIB_PHP;                           \
  file = g_vmContext->lookupPhpFile(systemlibPath.get(), currentDir.data(),   \
                                    NULL);                                    \
} while (0)
#define LOOKUP_ENV(v) do {                                                    \
  if (!file) {                                                                \
    const char* s = getenv(#v);                                               \
    if (s && *s) {                                                            \
      LOOKUP_STR(s);                                                          \
    }                                                                         \
  }                                                                           \
} while (0)
#define LOOKUP_CPP(v) do {                                                    \
  if (!file) {                                                                \
    LOOKUP_STR(v);                                                            \
  }                                                                           \
} while (0)

  LOOKUP_ENV(HHVM_LIB_PATH);
  if (!file) {
    char hhvm_exe[PATH_MAX+1];
    char hhvm_path[PATH_MAX+1];
    ssize_t len = readlink("/proc/self/exe", hhvm_exe, sizeof(hhvm_exe));
    if (len >= 0) {
      hhvm_exe[len] = '\0';
      if (realpath(hhvm_exe, hhvm_path) != NULL) {
        char *hphp_lib = dirname(hhvm_path);
        LOOKUP_STR(hphp_lib);
      }
    }
  }
  LOOKUP_ENV(HPHP_LIB);
#ifdef HHVM_LIB_PATH_DEFAULT
  LOOKUP_CPP(HHVM_LIB_PATH_DEFAULT);
#endif
  if (!file) {
    // Die a horrible death.
    Logger::Error("Unable to find/load systemlib.php");
    _exit(1);
  }
#undef SYSTEMLIB_PHP
#undef LOOKUP_STR
#undef LOOKUP_ENV
#undef LOOKUP_CPP
  SystemLib::s_phpFile = file;
  file->incRef();
  SystemLib::s_unit = file->unit();

  // Load the systemlib unit to build the Class objects
  SystemLib::s_unit->merge();

  // load builtins
  SystemLib::s_nativeFuncUnit->merge();

#define INIT_SYSTEMLIB_CLASS_FIELD(cls)                                 \
  {                                                                     \
    Class *cls = *Unit::GetNamedEntity(s_##cls.get())->clsList();       \
    ASSERT(cls);                                                        \
    SystemLib::s_##cls##Class = cls;                                    \
  }

  // Stash a pointer to the VM Classes for stdclass, Exception,
  // pinitSentinel and resource
  INIT_SYSTEMLIB_CLASS_FIELD(stdclass);
  INIT_SYSTEMLIB_CLASS_FIELD(Exception);
  INIT_SYSTEMLIB_CLASS_FIELD(BadMethodCallException);
  INIT_SYSTEMLIB_CLASS_FIELD(Directory);
  INIT_SYSTEMLIB_CLASS_FIELD(RecursiveDirectoryIterator);
  INIT_SYSTEMLIB_CLASS_FIELD(SplFileInfo);
  INIT_SYSTEMLIB_CLASS_FIELD(SplFileObject);
  INIT_SYSTEMLIB_CLASS_FIELD(pinitSentinel);
  INIT_SYSTEMLIB_CLASS_FIELD(resource);
  INIT_SYSTEMLIB_CLASS_FIELD(DOMException);
  INIT_SYSTEMLIB_CLASS_FIELD(PDOException);
  INIT_SYSTEMLIB_CLASS_FIELD(SoapFault);

#undef INIT_SYSTEMLIB_CLASS_FIELD

  // We call a special bytecode emitter function to build the native
  // unit which will contain all of our cppext functions and classes.
  // Each function and method will have a bytecode body that will thunk
  // to the native implementation.
  Unit* nativeClassUnit = build_native_class_unit(hhbc_ext_classes,
                                                  hhbc_ext_class_count);
  SystemLib::s_nativeClassUnit = nativeClassUnit;

  // Load the nativelib unit to build the Class objects
  SystemLib::s_nativeClassUnit->merge();

  // Retrieve all of the class pointers
  for (long long i = 0LL; i < hhbc_ext_class_count; ++i) {
    const HhbcExtClassInfo* info = hhbc_ext_classes + i;
    const StringData* name = StringData::GetStaticString(info->m_name);
    const NamedEntity* ne = Unit::GetNamedEntity(name);
    Class* cls = Unit::lookupClass(ne);
    ASSERT(cls);
    const ObjectStaticCallbacks* osc =
      get_object_static_callbacks(info->m_name);
    ASSERT(osc != NULL);
    *(osc->os_cls_ptr) = cls;
  }

  Stack::ValidateStackSize();
  SystemLib::s_inited = true;

  // For debug build, run some quick unit tests at process start time
  if (debug) {
    VM::Transl::FixupMapUnitTest _;
  }
}