Esempio n. 1
0
Variant f_class_parents(const Variant& obj, bool autoload /* = true */) {
    Class* cls;
    if (obj.isString()) {
        cls = Unit::getClass(obj.getStringData(), autoload);
        if (!cls) {
            return false;
        }
    } else if (obj.isObject()) {
        cls = obj.getObjectData()->getVMClass();
    } else {
        return false;
    }
    Array ret(Array::Create());
    for (cls = cls->parent(); cls; cls = cls->parent()) {
        ret.set(cls->nameStr(), VarNR(cls->name()));
    }
    return ret;
}
Variant HHVM_FUNCTION(get_class, const Variant& object /* = null_variant */) {
  if (object.isNull()) {
    // No arg passed.
    String ret;
    CallerFrame cf;
    auto cls = arGetContextClassImpl<true>(cf());
    if (cls) {
      ret = String(cls->nameStr());
    }

    if (ret.empty()) {
      raise_warning("get_class() called without object from outside a class");
      return false;
    }
    return ret;
  }
  if (!object.isObject()) return false;
  return VarNR(object.toObject()->getClassName());
}
Esempio n. 3
0
Variant f_class_implements(const Variant& obj, bool autoload /* = true */) {
    Class* cls;
    if (obj.isString()) {
        cls = Unit::getClass(obj.getStringData(), autoload);
        if (!cls) {
            return false;
        }
    } else if (obj.isObject()) {
        cls = obj.getObjectData()->getVMClass();
    } else {
        return false;
    }
    Array ret(Array::Create());
    const Class::InterfaceMap& ifaces = cls->allInterfaces();
    for (int i = 0, size = ifaces.size(); i < size; i++) {
        ret.set(ifaces[i]->nameStr(), VarNR(ifaces[i]->name()));
    }
    return ret;
}
Esempio n. 4
0
void EventHook::RunUserProfiler(const ActRec* ar, int mode) {
  // Don't do anything if we are running the profiling function itself
  // or if we haven't set up a profiler.
  if (g_vmContext->m_executingSetprofileCallback ||
      g_vmContext->m_setprofileCallback.isNull()) {
    return;
  }
  // Don't profile 86ctor, since its an implementation detail,
  // and we dont guarantee to call it
  if (ar->m_func->cls() && ar->m_func == ar->m_func->cls()->getCtor() &&
      Func::isSpecial(ar->m_func->name())) {
    return;
  }
  Transl::VMRegAnchor _;
  ExecutingSetprofileCallbackGuard guard;

  Array params;
  Array frameinfo;

  if (mode == ProfileEnter) {
    params.append(s_enter);
    frameinfo.set(s_args, hhvm_get_frame_args(ar));
  } else {
    params.append(s_exit);
    if (!g_vmContext->m_faults.empty()) {
      Fault fault = g_vmContext->m_faults.back();
      if (fault.m_faultType == Fault::Type::UserException) {
        frameinfo.set(s_exception, fault.m_userException);
      }
    } else if (!ar->m_func->info() &&
               !ar->m_func->isGenerator()) {
      // TODO (#1131400) This is wrong for builtins
      frameinfo.set(s_return, tvAsCVarRef(g_vmContext->m_stack.topTV()));
    }
  }

  params.append(VarNR(ar->m_func->fullName()));
  params.append(frameinfo);

  vm_call_user_func(g_vmContext->m_setprofileCallback, params);
}
Esempio n. 5
0
Variant f_class_uses(const Variant& obj, bool autoload /* = true */) {
  Class* cls;
  if (obj.isString()) {
    cls = Unit::getClass(obj.getStringData(), autoload);
    if (!cls) {
      String err = "class_uses(): Class %s does not exist";
      if (autoload) {
        err += " and could not be loaded";
      }
      raise_warning(err.c_str(), obj.toString().c_str());
      return false;
    }
  } else if (obj.isObject()) {
    cls = obj.getObjectData()->getVMClass();
  } else {
    raise_warning("class_uses(): object or string expected");
    return false;
  }
  Array ret(Array::Create());
  for (auto const& traitName : cls->preClass()->usedTraits()) {
    ret.set(StrNR(traitName), VarNR(traitName));
  }
  return ret;
}
Esempio n. 6
0
bool EventHook::RunInterceptHandler(ActRec* ar) {
  const Func* func = ar->func();
  if (LIKELY(func->maybeIntercepted() == 0)) return true;

  // Intercept only original generator / async function calls, not resumption.
  if (ar->resumed()) return true;

  Variant* h = get_intercept_handler(func->fullNameStr(),
                                     &func->maybeIntercepted());
  if (!h) return true;

  /*
   * In production mode, only functions that we have assumed can be
   * intercepted during static analysis should actually be
   * intercepted.
   */
  if (RuntimeOption::RepoAuthoritative &&
      !RuntimeOption::EvalJitEnableRenameFunction) {
    if (!(func->attrs() & AttrInterceptable)) {
      raise_error("fb_intercept was used on a non-interceptable function (%s) "
                  "in RepoAuthoritative mode", func->fullName()->data());
    }
  }

  VMRegAnchor _;

  PC savePc = vmpc();

  Variant doneFlag = true;
  Variant called_on;

  if (ar->hasThis()) {
    called_on = Variant(ar->getThis());
  } else if (ar->hasClass()) {
    // For static methods, give handler the name of called class
    called_on = Variant(const_cast<StringData*>(ar->getClass()->name()));
  }
  Variant intArgs =
    PackedArrayInit(5)
      .append(VarNR(ar->func()->fullName()))
      .append(called_on)
      .append(get_frame_args_with_ref(ar))
      .append(h->asCArrRef()[1])
      .appendRef(doneFlag)
      .toArray();

  Variant ret = vm_call_user_func(h->asCArrRef()[0], intArgs);
  if (doneFlag.toBoolean()) {
    Offset pcOff;
    ActRec* outer = g_context->getPrevVMState(ar, &pcOff);

    frame_free_locals_inl_no_hook<true>(ar, ar->func()->numLocals());
    Stack& stack = vmStack();
    stack.top() = (Cell*)(ar + 1);
    cellDup(*ret.asCell(), *stack.allocTV());

    vmfp() = outer;
    vmpc() = outer ? outer->func()->unit()->at(pcOff) : nullptr;

    return false;
  }
  vmfp() = ar;
  vmpc() = savePc;

  return true;
}
Esempio n. 7
0
static Variant get_breakpoint_message(const BreakInfo& bi) {
  if (auto eb = boost::get<ExnBreak>(&bi)) return VarNR(eb->message);
  return init_null();
}
Esempio n. 8
0
void ThriftBuffer::write(CObjRef data) {
    VariableSerializer vs(m_serializerType);
    String sdata = vs.serialize(VarNR(data), true);
    write(sdata);
}
Esempio n. 9
0
bool UnitEmitter::insert(UnitOrigin unitOrigin, RepoTxn& txn) {
  Repo& repo = Repo::get();
  UnitRepoProxy& urp = repo.urp();
  int repoId = Repo::get().repoIdForNewUnit(unitOrigin);
  if (repoId == RepoIdInvalid) {
    return true;
  }
  m_repoId = repoId;

  try {
    {
      m_lineTable = createLineTable(m_sourceLocTab, m_bclen);
      urp.insertUnit[repoId].insert(*this, txn, m_sn, m_md5, m_bc,
                                    m_bclen);
    }
    int64_t usn = m_sn;
    urp.insertUnitLineTable(repoId, txn, usn, m_lineTable);
    for (unsigned i = 0; i < m_litstrs.size(); ++i) {
      urp.insertUnitLitstr[repoId].insert(txn, usn, i, m_litstrs[i]);
    }
    for (unsigned i = 0; i < m_arrays.size(); ++i) {
      VariableSerializer vs(VariableSerializer::Type::Serialize);
      urp.insertUnitArray[repoId].insert(
        txn, usn, i,
        vs.serializeValue(VarNR(m_arrays[i]), false /* limit */).toCppString()
      );
    }
    for (auto& fe : m_fes) {
      fe->commit(txn);
    }
    for (auto& pce : m_pceVec) {
      pce->commit(txn);
    }

    for (int i = 0, n = m_mergeableStmts.size(); i < n; i++) {
      switch (m_mergeableStmts[i].first) {
        case MergeKind::Done:
        case MergeKind::UniqueDefinedClass:
          not_reached();
        case MergeKind::Class: break;
        case MergeKind::TypeAlias:
        case MergeKind::ReqDoc: {
          urp.insertUnitMergeable[repoId].insert(
            txn, usn, i,
            m_mergeableStmts[i].first, m_mergeableStmts[i].second, nullptr);
          break;
        }
        case MergeKind::Define:
        case MergeKind::PersistentDefine:
        case MergeKind::Global: {
          int ix = m_mergeableStmts[i].second;
          urp.insertUnitMergeable[repoId].insert(
            txn, usn, i,
            m_mergeableStmts[i].first,
            m_mergeableValues[ix].first, &m_mergeableValues[ix].second);
          break;
        }
      }
    }
    if (RuntimeOption::RepoDebugInfo) {
      for (size_t i = 0; i < m_sourceLocTab.size(); ++i) {
        SourceLoc& e = m_sourceLocTab[i].second;
        Offset endOff = i < m_sourceLocTab.size() - 1
                          ? m_sourceLocTab[i + 1].first
                          : m_bclen;

        urp.insertUnitSourceLoc[repoId]
           .insert(txn, usn, endOff, e.line0, e.char0, e.line1, e.char1);
      }
    }
    return false;
  } catch (RepoExc& re) {
    TRACE(3, "Failed to commit '%s' (0x%016" PRIx64 "%016" PRIx64 ") to '%s': %s\n",
             m_filepath->data(), m_md5.q[0], m_md5.q[1],
             repo.repoName(repoId).c_str(), re.msg().c_str());
    return true;
  }
}
Esempio n. 10
0
ArrayData* ArrayData::nvSet(int64 ki, int64 vi, bool copy) {
  return set(ki, VarNR(vi), copy);
}