Ejemplo n.º 1
0
TypedValue* zend_wrap_func(ActRec* ar) {
  TSRMLS_FETCH();
  zend_ext_func native_func = reinterpret_cast<zend_ext_func>(ar->func()->nativeFuncPtr());

  // Prepare the arguments and return value before they are
  // exposed to the PHP extension
  zPrepArgs(ar);

  // Using Variant so exceptions will decref them
  Variant return_value_var(Variant::NullInit{});
  auto const return_value = return_value_var.asTypedValue();
  tvBox(return_value);

  Variant this_ptr_var(Variant::NullInit{});
  auto const this_ptr = this_ptr_var.asTypedValue();
  tvBox(this_ptr);

  if (ar->hasThis()) {
    tvWriteObject(
      ar->getThis(),
      this_ptr->m_data.pref->tv()
    );
  }

  auto *return_value_ptr = &return_value->m_data.pref;

  // Clear any stored exception
  zend_clear_exception(TSRMLS_C);

  // Invoke the PHP extension function/method
  ZendExecutionStack::pushHHVMStack();
  try {
    native_func(
      ar->numArgs(),
      return_value->m_data.pref,
      return_value_ptr,
      this_ptr_var.isNull() ? nullptr : this_ptr->m_data.pref,
      1
      TSRMLS_CC
    );
  } catch (...) {
    ZendExecutionStack::popHHVMStack();
    throw;
  }
  ZendExecutionStack::popHHVMStack();

  // If an exception was caught, rethrow it
  ZendExceptionStore& exceptionStore = ZendExceptionStore::getInstance();
  if (!exceptionStore.empty()) {
    exceptionStore.rethrow();
  }

  // Take care of freeing the args, tearing down the ActRec,
  // and moving the return value to the right place
  frame_free_locals_inl(ar, ar->func()->numLocals(), return_value);
  memcpy(&ar->m_r, return_value, sizeof(TypedValue));
  return_value->m_type = KindOfNull;
  if (ar->func()->isReturnRef()) {
    if (!ar->m_r.m_data.pref->isReferenced()) {
      tvUnbox(&ar->m_r);
    }
  } else {
    tvUnbox(&ar->m_r);
  }

  return &ar->m_r;
}
Ejemplo n.º 2
0
TypedValue* zend_wrap_func(ActRec* ar) {
  // Sync the translator state.
  // We need to do this before a native function calls into a C library
  // compiled with -fomit-frame-pointer with the intention of having it call
  // back. Normal HHVM extensions have the luxury of only when such a thing
  // will be attempted, but we have no way to know in advance.
  VMRegAnchor _;

  TSRMLS_FETCH();
  zend_ext_func native_func = reinterpret_cast<zend_ext_func>(ar->func()->nativeFuncPtr());

  // Using Variant so exceptions will decref them
  Variant return_value_var(Variant::NullInit{});
  auto const return_value = return_value_var.asTypedValue();
  tvBox(return_value);

  Variant this_ptr_var(Variant::NullInit{});
  auto const this_ptr = this_ptr_var.asTypedValue();
  tvBox(this_ptr);

  if (ar->func()->cls() && ar->hasThis()) {
    tvWriteObject(
      ar->getThis(),
      this_ptr->m_data.pref->tv()
    );
  }

  auto *return_value_ptr = &return_value->m_data.pref;

  // Clear any stored exception
  zend_clear_exception(TSRMLS_C);

  // Invoke the PHP extension function/method
  ZendExecutionStack::pushHHVMStack((void*)ar);
  try {
    native_func(
      ar->numArgs(),
      return_value->m_data.pref,
      return_value_ptr,
      this_ptr_var.isNull() ? nullptr : this_ptr->m_data.pref,
      1
      TSRMLS_CC
    );
  } catch (...) {
    zend_wrap_func_cleanup();
    throw;
  }
  zend_wrap_func_cleanup();

  // If an exception was caught, rethrow it
  ZendExceptionStore& exceptionStore = ZendExceptionStore::getInstance();
  if (!exceptionStore.empty()) {
    exceptionStore.rethrow();
  }

  // Take care of freeing the args, tearing down the ActRec, and moving the
  // return value to the right place.  Note that frame_free_locals expects to
  // be able to free return_value in the event of an exception, so we have to
  // take it out of our Variant /before/ calling that.
  TypedValue return_value_copy = *return_value;
  return_value->m_type = KindOfNull; // clear the Variant's copy
  frame_free_locals_inl(ar, ar->func()->numLocals(), &return_value_copy);
  memcpy(&ar->m_r, &return_value_copy, sizeof(TypedValue));
  if (ar->func()->isReturnRef()) {
    if (!ar->m_r.m_data.pref->isReferenced()) {
      tvUnbox(&ar->m_r);
    }
  } else {
    tvUnbox(&ar->m_r);
  }

  return &ar->m_r;
}
void* Call(Callable native_func, ArgTypes&&... args) noexcept
{
	std::clog << "in Call" << std::endl;
	return native_func(std::forward<ArgTypes>(args)...);
}