Пример #1
0
bool invoke_file_impl(Variant &res, const String& path, bool once,
                      const char *currentDir) {
  bool initial;
  HPHP::Eval::PhpFile* efile =
    g_context->lookupPhpFile(path.get(), currentDir, &initial);
  HPHP::Unit* u = nullptr;
  if (efile) u = efile->unit();
  if (u == nullptr) {
    return false;
  }
  if (!once || initial) {
    g_context->invokeUnit((TypedValue*)(&res), u);
  }
  return true;
}
Пример #2
0
bool eval_invoke_file_hook(Variant &res, CStrRef path, bool once,
                           LVariableTable* variables, const char *currentDir) {
  bool initial;
  HPHP::Eval::PhpFile* efile =
    g_vmContext->lookupPhpFile(path.get(), currentDir, &initial);
  HPHP::VM::Unit* u = nullptr;
  if (efile) u = efile->unit();
  if (u == nullptr) {
    return false;
  }
  if (!once || initial) {
    g_vmContext->invokeUnit((TypedValue*)(&res), u);
  }
  return true;
}
Пример #3
0
bool eval_invoke_file_hook(Variant &res, CStrRef path, bool once,
                           LVariableTable* variables, const char *currentDir) {
  if (hhvm) {
    bool initial;
    HPHP::Eval::PhpFile* efile =
      g_vmContext->lookupPhpFile(path.get(), currentDir, &initial);
    HPHP::VM::Unit* u = NULL;
    if (efile) u = efile->unit();
    if (u == NULL) {
      return false;
    }
    if (!once || initial) {
      g_vmContext->invokeUnit((TypedValue*)(&res), u);
    }
    return true;
  } else {
    return RequestEvalState::includeFile(res, path, once, variables,
                                         currentDir);
  }
}
Пример #4
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 _;
  }
}