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(); }
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; }
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 _; } }